Когда я начал тестирование решения, которое я придумал против производительности данных производства было гораздо более приемлемым, так что я собираюсь свернуть с ним сейчас ограничивающими пользователями 1 год объемом данных в течение доклада ,
В дополнение к данным журнала, я создал таблицу, содержащую даты от 2010-2050, так что я не должен генерировать даты каждого запуска, это то, что я придумал:
--Variables for outer cursor
DECLARE @ID INT
,@StartDate DATETIME
,@EndDate DATETIME
,@LineID TINYINT
,@DTCode SMALLINT
--Table var to hold results
DECLARE @ResultTbl AS TABLE (
[Date] DATE
,Line TINYINT
,DTCode SMALLINT
,MinDiff INT
)
--Declare cursor to loop through log data
DECLARE IDCur CURSOR local fast_forward FOR
SELECT ID
,StartTime
,EndTime
,EquipmentID
,dtcode
FROM DowntimeLog
OPEN IDCur
FETCH NEXT FROM IDCur INTO @ID, @StartDate, @EndDate, @LineID, @DTCode
WHILE @@FETCH_STATUS = 0
BEGIN
--Check if the entry spans multiple days
IF DATEDIFF(DAY,@StartDate,@EndDate) > 0
BEGIN
--Declare cursor to loop through each date that pertains to the entry
DECLARE @D DATE
DECLARE applicableDates CURSOR LOCAL fast_forward FOR
SELECT tDate
FROM DateTbl
WHERE tDate BETWEEN CAST(@StartDate AS DATE) AND CAST(@EndDate AS DATE)
OPEN applicableDates
FETCH NEXT FROM applicableDates INTO @D
WHILE @@FETCH_STATUS = 0
BEGIN
--Determine if @D is the first date
IF (SELECT CAST(@StartDate AS DATE)) = @D
BEGIN
--If @D is the first date insert result row with minutes between start & 00:00 the next day
INSERT INTO @ResultTbl (
[Date]
,Line
,DTCode
,MinDiff)
VALUES (
@D
,@LineID
,@DTCode
,(SELECT DATEDIFF(MINUTE,@StartDate,DATEADD(DAY,1,@D))))
END
ELSE
BEGIN
--Determine if @D is the last date
IF (SELECT DATEDIFF(MINUTE,@D,@EndDate)) < 1440
BEGIN
--If @D is the last date insert result row with minutes between @D 00:00 and end of downtime
INSERT INTO @ResultTbl (
[Date]
,Line
,DTCode
,MinDiff)
VALUES (
@D
,@LineID
,@DTCode
,(SELECT DATEDIFF(MINUTE,@D,@EndDate)))
END
ELSE
BEGIN
--If @D is not first or last date insert result row for the full day
INSERT INTO @ResultTbl (
[Date]
,Line
,DTCode
,MinDiff)
VALUES (
@D
,@LineID
,@DTCode
,1440)
END
END
FETCH NEXT FROM applicableDates INTO @D
END
CLOSE applicableDates
DEALLOCATE applicableDates
END
ELSE
BEGIN
--Entry does not span multiple days, insert result row with diff between start & end
INSERT INTO @ResultTbl (
[Date]
,Line
,DTCode
,MinDiff)
VALUES (
CAST(@StartDate AS DATE)
,@LineID
,@DTCode
,(SELECT DATEDIFF(MINUTE,@StartDate,@EndDate)))
END
FETCH NEXT FROM IDCur INTO @ID, @StartDate, @EndDate, @LineID, @DTCode
END
CLOSE IDCur
DEALLOCATE IDCur
--Display Result
SELECT [Date]
,Line
,DTCode
,SUM(MinDiff) AS MinDown
FROM @ResultTbl
GROUP BY [Date],Line,DTCode