SQL Server insert: using a static value to determine date value [closed] - sql-server

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am inserting production orders into a SQL Server database with a stored procedure called via Microsoft PowerApps. Currently, the build date column is just using today's date as the build date. Attached below is a sample of records:
As you can see, all 10 of these orders have today's date as the set build date. However, I'd like to dynamically set this build date based upon the necessary output for the day. This will most likely be passed a variable to the stored procedure. For example - if the build output was 5 per day, rows 1-5 would have a build date of '02/17/2020' while the next 5 would have have a build date of '02/18/2020'.
This is simple enough since the number of orders is divisible by the build output. However, let's say the build output is 3 instead of 5. The first three orders would be '02/17/2020', the next three would be '02/18/2020', and the next three would be '02/19/2020'. This would leave one order to be set to '02/20/2020'. Then if I added more orders, it would stack upon each date filling each up to 3. Is there a way to do this via a stored procedure?

You might need to do some adjustments but based on my understanding, this will do the trick ([Date] is the date column in your sample table above):
CREATE PROC yourProcName #pNUM AS INT = 1 --PARAMETER
AS
(
DECLARE #pDate DATE;
SET #pDate = COALESCE((SELECT TOP 1 CONVERT(DATE, MAX([Date])), GETDATE()) FROM yourDestTable); --SETTING THE DATE AS MAX DATE ALREADY EXISTS IN THE TABLE. IF NOTHING IS THERE, WE'LL USE TODAY
DECLARE #pLead INT = COALESCE((SELECT TOP 1 COUNT(*) FROM yourDestTable WHERE [Date] = #pDate), 0);--SEE HOW MANY RECORDS IN THE DATABASE EXIST WITH THE DATE WE DEFINED
WITH cte
AS
(
SELECT *,
FLOOR((
ROW_NUMBER() OVER(ORDER BY #pDate) -
0.001)/#pNUM) AS RN -- SEPARATING RECORDS USING ROW_NUMBER DIVIDED BY DEFINED NUMBER OF PRODS PER DAY. USING FLOOR AND MINUS A SMALL AMOUNT TO ROUND IT RIGHT
FROM yourSourceTable
)
INSERT INTO yourDestTable
SELECT
C.*,
DATEADD(DAY, LEAD(C.RN, #pLead), #pDate) AS [Date] --PUSHING THE NUMBER BASED ON ROWS ALREADY EXISTED WITH THE MAX_DATE
INTO yourDestTable
FROM cte AS C
)
You might want to use MOD in CTE based on your usecase. But the idea should work. Then call it like this EXEC yourProcName <number of transactionsday>

Related

T-SQL how to properly union date and time in datetime [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 21 hours ago.
This post was edited and submitted for review 10 hours ago.
Improve this question
dear gurus, SQL.
Please advise how to do the following:
You need to take a date from one column and join it with the time of another column,
and then add one day to the received date.
I wrote such a query, but on some data it gives a conversion error.
Please tell me a more optimal query so that it always works when combining the date and time format into datetime.
Thank you.
create table dt (date1 datetime, date2 datetime)
insert into dt values('19000101 17:17:00.000','19070101 17:51:00.000')
insert into dt values('19000101 18:20:00.000','19080101 18:21:00.000')
insert into dt values('20000101 06:00:00.000','20100101 06:40:00.000')
select
dateadd(dd,1,convert(datetime,convert(date,date1))+ convert(datetime,convert(time, date2)))
from dt
Here is an example where such an error could occur:
CREATE TABLE Example (
Duration TIME,
AdditionalDelay SMALLINT
)
INSERT INTO dbo.Example (Duration, AdditionalDelay)
VALUES ('00:01:02',3)
SELECT Duration+AdditionalDelay FROM dbo.Example
To fix this, you need to identify the proper unit of measure for AdditionalDelay and use DATEADD instead of +. For example:
SELECT DATEADD(MINUTE,AdditionalDelay,Duration) FROM dbo.Example

Find increasing values by year [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have a table that contains a list of debts owed by customers. I need to write a SQL query to find which customers have an increasing amount of debt each year. Basically, I am trying to find the "bad apples", the people who continually get debts, in an increasing amount, every year. I suppose I am looking for a trend?
I have created a SQL Fiddle with some sample data. In the example, I don't care about customerId 2174 as they have only had two debts, many years ago, however, customerId 5218 has had an increasing amount of debts over the last 3-4 years.
Ideally, I'd like a list of customerIds that show a "trend" of increasing quantity of debts. i.e. they have 1 in 2015, 5 in 2016, 30 in 2017 etc.
You may try this.
; with cte as
(SELECT customerId
,YEAR(debtDate) AS debtYear
,COUNT(*) AS debtCount
FROM dbo.Debts
----- apply year filter over there if want to select record for particular year range
GROUP BY YEAR(debtDate)
,customerId
)
, CT AS
(
SELECT C.* FROM CTE AS C
CROSS APPLY (
SELECT * FROM CTE AS CC
WHERE C.customerId=CC.customerId
AND C.debtYear>CC.debtYear
AND C.debtCount>=CC.debtCount
) AS D
)
SELECT DISTINCT customerId FROM CT --- IF NEED JUST CUSTOMER NAME
------- OR IF NEED ALL DETAILS ADD debtYear, debtCount COLUMN

tsql between two dates which can be null [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm new in TSQL.
I need to write a stored procedure which returns filtered records.
So the user has two dates to enter. He may enter only one date, or two, or both, or any.
In stored proc I have two params #From, #To - date type.
I need to search records.
If user didn't enter dates - I don't care about dates in the select query.
If the user entered 2 dates - I need to search with them inclusively.
If the user entered #From date - I need to search up to today inclusively.
If the user entered #To date - I need to search dates less than #To.
Thanks for your help.
SELECT ColumnList
FROM MyTable
WHERE
(#FromDate IS NULL OR FromDateColumn >= #FromDate)
AND (#ToDate IS NULL OR ToDateColumn <= #ToDate )
(But be aware that this can suffer from the effects of an unsuitable cached query plan due to parameter sniffing, especially if there is a large number of parameter conditions in the WHERE clause)
SELECT
Columns
FROM
Table
WHERE
DateColumn BETWEEN (CASE WHEN #FromDate IS NULL THEN DateColumn ELSE #FromDate END)
AND (CASE WHEN #ToDate IS NULL THEN DateColumn ELSE #ToDate END)

Give me best possible loop to iterate in sql with performance [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
suppose i have two table and both tables consist of one date column eg
OUTTime
12:05:40
12:08:30
12:20:40
and other table consist of
INTime
12:10:35
12:12:23
12:16:40
12:30:11
Now i want rows with Minimum time difference between two tables like 12:08:30 and 12:10:35 gives me OUT and IN. Similarly 12:20:40 and 12:30:11 gives me another row here by eliminating OUTTime 12:05:40 and eliminating 12:12:35 and 12:16:40 from INTime which gives me proper OUtTime and InTime
Any suggestion how to loop to get this data?
If you want to get a matching InTimes and OutTimes and only get the closest, try this:
Set Up
CREATE TABLE #OUTTime
(
[Time] Time
)
INSERT INTO #OUTTime
VALUES
('12:05:40'),
('12:08:30'),
('12:20:40')
CREATE TABLE #InTime
(
[Time] Time
)
INSERT INTO #InTime
VALUES
('12:10:35'),
('12:12:23'),
('12:16:40'),
('12:30:11')
Now the query:
;WITH CTE
As
(
SELECT O.Time AS outTime, (SELECT MIN([Time]) FROM #InTime I WHERE I.[time] > O.[Time]) AS InTime
FROM #OUTTime O
)
SELECT MAX(OutTime) As OutTime, InTime
FROM CTE
GROUP BY InTime
Results
OutTime InTime
12:08:30.0000000 12:10:35.0000000
12:20:40.0000000 12:30:11.0000000
If you UNION the two tables ... something like
SELECT Time, 'IN'
FROM InTimesTable
UNION
SELECT Time, 'Out'
FROM OutTimesTable
Order by Time
You can dump it in excel, and manipulate it manually.
Or, you can fill out your question here, and get a better answer.

SSAS - Facts that happened over a time range

I don't really know how to handle facts that happened over a period of time. I sually deal with facts that happened on a specific date.
In clear, my facts have a start_date and an end_date. So, let's say my start_date is 01/01/2008 and my end_date is 01/01/2011. I need to get the number of those facts that happened in 2009 and those that happened this year. The same fact can have happened on both years. The way to determine a fact is part of 2009 is to check for 12/31/2009.
I was thinking about a StartDate and EndDate dimensions, using date ranges (so from the first date of my StartDate dimension to 12/31/2009 and from 12/31/2009 to the last date in my EndDate dimension). I would cross join those.
I tried it, it works, but it's REALLY slow.
Any thoughts?
I found the solution to what I wanted. David and Chris for the anwsers tho! Here's what I wanted to achieve, but I was lacking MDX syntax :
SELECT [Measures].[NumberX] ON COLUMNS
FROM [MyCube]
WHERE ([START DATE].[REFDATE].FirstMember:[START DATE].[REFDATE].&[2009-12-31T00:00:00],
[END DATE].[REFDATE].&[2010-01-01T00:00:00]:[END DATE].[REFDATE].LastMember)
Pretty simple. I think my question was not clear, that's why I got different answers ;-)
You can always use a date range with the two time dimensions like:
Select [start date].[year].[2009]:[end date].[year].[2010] on 0
from cube
If I'm understanding the question correctly. Two time dimensions should work together fine. I have two in a project I'm doing at work and they work rather fast together. Make sure that you set them up in dimension usage section of the cube so you can differentiate the two dates.
You just need one Date dimension DimDate. Your fact table can have 2 foreign keys to the DimDate, one for startdate and one for enddate.
FactTable
{
FactID int,
StartDate int,
EndDate int
-- Other fields
}
DimDate
{
DimDateID int,
Year int,
Month int,
Day int,
-- Other fields if needed
}
To get all facts that fall on the year 2009, use
SELECT f.FactID FROM FactTable f
INNER JOIN DimDate dStart ON dStart.DimDateID = f.StartDate
INNER JOIN DimDate dEnd ON dEnd.DimDateID = f.EndDate
WHERE dStart.Year <= 2009
AND dEnd.Year >= 2009

Resources