长话短说我今天在生产存储过程中发现了一个问题,我们用它来记录来自我们PLC的数据,存储过程的一部分是当一行停机时将行插入日志表。当存储过程记录这些条目时,没有记录正确的开始时间,所以除了开始时间之外我有我的所有数据,如果我能弄清楚如何从我们的其余数据中确定我&# 39;没关系。
我们正在运行SQL Server 2012,并且我尝试了一些主要使用LAG()
的解决方案,但我还没有能够正确使用分区子句。
sqlfiddle似乎在2012年失败了(由于IOException"架构构建错误,我得到了一个"无法连接到数据源)所以不幸的是,我所拥有的只是T-而不是T-用于样本数据的SQL。
CREATE TABLE LogData
(
LogID INT IDENTITY(1,1) NOT NULL --ID Column
,LogTime DATETIME NOT NULL --TimeStamp Column
,LogLineID INT NOT NULL --Machine number
,LogCycles INT NOT NULL --Machine cycle count
,LogUptime decimal(5,2) --% Machine uptime across 5 min cycles
)
--"Downtime" is defined as [LogUptime] < 0.10
INSERT INTO LogData (LogTime, LogLineID, LogCycles, LogUptime)
VALUES
('01/01/2014 00:05:00', 1, 90, 0.85)
,('01/01/2014 00:05:00', 2, 100, 1.0)
,('01/01/2014 00:10:00', 1, 50, 0.25)
,('01/01/2014 00:10:00', 2, 100, 1.0)
,('01/01/2014 00:15:00', 1, 0, 0.01) --Start of Downtime...what I want to determine
,('01/01/2014 00:15:00', 2, 100, 1.0)
,('01/01/2014 00:20:00', 1, 0, 0.0)
,('01/01/2014 00:20:00', 2, 100, 1.0)
,('01/01/2014 00:25:00', 1, 0, 0.0)
,('01/01/2014 00:25:00', 2, 100, 1.0)
,('01/01/2014 00:30:00', 1, 10, 0.04)
,('01/01/2014 00:30:00',2,100,1.0)
,('01/01/2014 00:35:00',1,40,0.3) --End of Downtime...what I have
,('01/01/2014 00:35:00',2,100,1.0)
,('01/01/2014 00:40:00',1,100,1.0)
,('01/01/2014 00:40:00',2,100,1.0)
--***Desired Result***
SELECT '01/01/2014 00:15:00' AS StartTime
,'01/01/2014 00:35:00' AS EndTime
,1 AS LineID
编辑 - 添加了部分查询
我尝试在子查询中向数据集添加一个额外的列,表示该行是否已关闭该行,然后按该列进行分区并使用LAG()并使用MIN / MAX来代替落后。 LAG只返回下一行的时间,MIN返回整个数据集中忽略分区的最小值。
SELECT LogTime AS StartTime
,LAG(LogTime) OVER (PARTITION BY LogLineUp ORDER BY LogTime DESC) AS EndTime
,LogLineID
,LogUptime
,LogLineUp
FROM (
SELECT LogTime
,LogLineID
,LogUptime
,CASE WHEN LogUptime < 0.1 THEN 0 ELSE 1 END AS LogLineUp
FROM LogData
WHERE LogLineID = 1
) T2
答案 0 :(得分:0)
感谢@VladimirBaranov修复了我的查询的LAG / LEAD部分,为我提供了一个有效的解决方案。这就是我最后的结果,我确信这种方法比嵌套的子查询更优雅,但有一次(希望)修复它对我有用。
查询的快速解释:
我将结果放在临时表中,然后通过使用LineID&amp; amp;将该表连接到临时表来对日志条目开始时间执行更新。 EndTime列。
SELECT StartTime
,EndTime
,LineID
FROM (
SELECT LogTime AS StartTime
,LEAD(LogTime) OVER (ORDER BY LDTime) AS EndTime
,LogLineID AS LineID
,PreviousState
FROM (
SELECT LogTime
,LAG(LineUp) OVER (PARTITION BY LogLineID ORDER BY LogTime) AS PreviousState
,LineUp AS NewState
,LogLineID
FROM (
SELECT LogTime
,LogLineID
,CASE WHEN LogUptime < 0.1 THEN 0 ELSE 1 END AS LineUp
FROM LogData
WHERE LogLineID = 1
) T4
) T3
WHERE PreviousState <> NewState
) T2
WHERE PreviousState = 1