无法通过搜索找到任何内容(尽管这可能是我的搜索字词),如果有人询问/回答,请致歉。
我们在MSSQL 2012中维护设备停机记录,我正在尝试报告按天,设备,DTCode分组的停机时间。我正在运行的问题是日志表包含start&每个事件和事件的结束日期经常跨越开始和结束之间的多天(或有时是几周)。
示例数据:
Start End Equipment DTCode
01/01/15 00:00 01/02/15 02:00 Line1 2
期望的结果:
Date Equipment DTCode Downtime(minutes)
01/01/15 Line1 2 1440
01/02/15 Line1 2 120
修改
好的,现在我有一个性能不佳的优雅解决方案,因为我能想到的唯一方法是使用嵌套游标。这是一个新的小提琴,有一个更大的数据集和我想要调整/优化的功能解决方案:
答案 0 :(得分:0)
如果您的意思是在两个"停机时间之间获得时间,您可以使用MYSQL连接获取PHP的值,并计算差异,然后删除这两行,并将其替换为新行,计算结果。
$query = "DELETE FROM TaBlEnAmEhErE WHERE DTCode=2";
答案 1 :(得分:0)
当我开始测试解决方案时,我提出了针对生产数据的性能更加可接受,所以我现在要用它来限制用户使用1年的报告数据范围。 / p>
除了日志数据之外,我创建了一个包含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