MS SQL server: CTE example
During one of my assignments I was asked to make a production report with the number of produced articles during a batch distributed evenly per hour between batch start and end.
This is how I solved it with a cursor and cte (common table expression)
--Variables
DECLARE
@BatchID int,
@startTime datetime,
@stopTime datetime,
@diffHours int,
@Article int,
@prodAmount int,
@theRest int,
@ProdLine int,
@endDiff int,
@amount int
DECLARE
@BatchID int,
@startTime datetime,
@stopTime datetime,
@diffHours int,
@Article int,
@prodAmount int,
@theRest int,
@ProdLine int,
@endDiff int,
@amount int
--Fetch the data
DECLARE prod_Cursor CURSOR FOR
SELECT BatchID, ProdLine, starttime, stoptime, article, prodAmount
FROM BatchLog
WHERE starttime=getDate() -- Or whatever statement you want
OPEN prod_Cursor
DECLARE prod_Cursor CURSOR FOR
SELECT BatchID, ProdLine, starttime, stoptime, article, prodAmount
FROM BatchLog
WHERE starttime=getDate() -- Or whatever statement you want
OPEN prod_Cursor
--Get the first row of data from the cursor
FETCH NEXT FROM prod_Cursor INTO
@BatchID, @ProdLine, @starttime, @stoptime, @article, @prodAmount
WHILE @@FETCH_STATUS = 0
BEGIN
SET @diffHours=DATEDIFF(HH,@starttime,@stoptime)+1 -- how many time slots to ditribute into
SET @amount=@prodAmount/@diffHours -- distribute amount of produced items
SET @theRest=@prodAmount-(@amount*@diffHours) -- left over if share isn't even
FETCH NEXT FROM prod_Cursor INTO
@BatchID, @ProdLine, @starttime, @stoptime, @article, @prodAmount
WHILE @@FETCH_STATUS = 0
BEGIN
SET @diffHours=DATEDIFF(HH,@starttime,@stoptime)+1 -- how many time slots to ditribute into
SET @amount=@prodAmount/@diffHours -- distribute amount of produced items
SET @theRest=@prodAmount-(@amount*@diffHours) -- left over if share isn't even
-- This is needed in order to get all started hours
SET @endDiff=CASE
WHEN (DATEPART(MI,@startTime)>=DATEPART(MI,@stopTime)) THEN 0
WHEN (DATEPART(MI,@startTime)<DATEPART(MI,@stopTime)) THEN -1
END
-- Create CTE table and store values
;WITH cte AS(
SELECT @BatchID AS BatchID, @prodLine as prodLine, @startTime As StartTime, @stopTime as StopTime, CONVERT(varchar, @StartTime, 23) AS Datum, @amount+@theRest as amount, @article AS article
UNION ALL
SELECT @BatchID AS BatchID, @prodLine as prodLine, DATEADD(HH, 1, startTime), @stoptime as StopTime, CONVERT(varchar, DATEADD(HH, 1, startTime), 23) AS Datum, @amount as amount, @article AS article
FROM cte
WHERE startTime < DateAdd(HH,@endDiff,@stopTime)
)
--Get the data from CTE
SELECT BatchID, prodLine, Starttime, StopTime, Datum, DATEPART(HH,StartTime) As [perHour], amount, article
FROM cte
FETCH NEXT FROM prod_Cursor INTO
@BatchID, @prodLine, @starttime, @stoptime, @article, @prodAmount
END
CLOSE prod_Cursor
DEALLOCATE prod_Cursor
SET @endDiff=CASE
WHEN (DATEPART(MI,@startTime)>=DATEPART(MI,@stopTime)) THEN 0
WHEN (DATEPART(MI,@startTime)<DATEPART(MI,@stopTime)) THEN -1
END
-- Create CTE table and store values
;WITH cte AS(
SELECT @BatchID AS BatchID, @prodLine as prodLine, @startTime As StartTime, @stopTime as StopTime, CONVERT(varchar, @StartTime, 23) AS Datum, @amount+@theRest as amount, @article AS article
UNION ALL
SELECT @BatchID AS BatchID, @prodLine as prodLine, DATEADD(HH, 1, startTime), @stoptime as StopTime, CONVERT(varchar, DATEADD(HH, 1, startTime), 23) AS Datum, @amount as amount, @article AS article
FROM cte
WHERE startTime < DateAdd(HH,@endDiff,@stopTime)
)
--Get the data from CTE
SELECT BatchID, prodLine, Starttime, StopTime, Datum, DATEPART(HH,StartTime) As [perHour], amount, article
FROM cte
FETCH NEXT FROM prod_Cursor INTO
@BatchID, @prodLine, @starttime, @stoptime, @article, @prodAmount
END
CLOSE prod_Cursor
DEALLOCATE prod_Cursor
Comments
Post a Comment