在SQL Server上计算切换间隔的秒数

在SQL Server上计算切换间隔的秒数,sql,sql-server,database,Sql,Sql Server,Database,我有一张这样的桌子: Value TimeStamp 1 2016-04-01 00:01:09.000 0 2016-04-01 00:01:09.000 0 2016-04-01 00:01:37.000 1 2016-04-01 00:01:37.000 1 2016-04-01 00:04:52.000 1 2016-04-01 00:09:58.000 1 2016-04-01 00:15:05.000 1 2016-04-01 00:20:11.000

我有一张这样的桌子:

Value TimeStamp
1   2016-04-01 00:01:09.000
0   2016-04-01 00:01:09.000
0   2016-04-01 00:01:37.000
1   2016-04-01 00:01:37.000
1   2016-04-01 00:04:52.000
1   2016-04-01 00:09:58.000
1   2016-04-01 00:15:05.000
1   2016-04-01 00:20:11.000
1   2016-04-01 00:24:49.000
1   2016-04-01 00:29:55.000
1   2016-04-01 00:31:19.000
0   2016-04-01 00:31:19.000
0   2016-04-01 00:31:46.000
1   2016-04-01 00:31:46.000
1   2016-04-01 00:35:01.000
1   2016-04-01 00:40:07.000
1   2016-04-01 00:44:46.000
1   2016-04-01 00:49:52.000
1   2016-04-01 00:54:58.000
1   2016-04-01 01:00:04.000
1   2016-04-01 01:01:28.000
0   2016-04-01 01:01:28.000
0   2016-04-01 01:05:10.000
0   2016-04-01 01:09:49.000
我想计算每天打开1次开关的秒数,这是交易;当时间戳重复时,这意味着开关值从0变为1,反之亦然,我已经有很多类似的方法:

Q1 AS (SELECT ROW_NUMBER() OVER (ORDER BY TimeStamp) AS id,
Value, Timestamp
FROM Q2
GROUP BY idVBox, sensorType, sensorSubtype, timeStamp
HAVING COUNT(TimeStamp) > 1)

Then:

SELECT A.Value, DATEDIFF(SECOND,A.TimeStamp,B.TimeStamp)
FROM Q1 AS A
INNER JOIN Q1 AS B
ON B.ID = A.ID + 1
AND B.ID%2 = 0

然后分组并求和,但这里的问题是,我不知道从过去的一天起值是1还是0,开关可以快速改变它的状态,并且永远不会得到它的实际状态的实际值。还有其他想法吗?

如果使用SQL Server 2012,则可以充分利用LAG函数。 首先,在value=1的重复日期加入表。接下来,计算on和上一个on之间的差值。最后,总结一下

注意:延迟将在当天的第一天返回null

SELECT 
    Seconds=SUM(X.Seconds)
FROM
(
    SELECT  
        Seconds=DATEDIFF(SECOND,LAG(T1.TimeStamp) OVER (ORDER BY T1.TimeStamp),T1.TimeStamp)    
    FROM
        MyTable T1
        INNER JOIN MyTable T2 ON T2.TimeStamp=T1.TimeStamp AND T1.Value<>T2.Value
    WHERE
        T1.Value=1
)AS X

您要做的是,在开始计算前的一天开始时,在集合中添加一个虚拟传感器状态开关

增加的额外记录包括:

0, '2016-04-01 00:00:00'
1, '2016-04-01 00:00:00' -- This is conditional on the first record in your set having a value of 1
下面是总体查询 注意:为了确定哪个记录实际上是序列中的第一个记录,我使用了ID列

;WITH Q0 AS(
    -- Inserts a new record ( 0, '2016-04-01 00:00:00' ) to the beginning of the day
    SELECT TOP 1 0 AS Value, CONVERT( DATETIME, CONVERT( DATE, LogDate )) AS LogDate
    FROM #SwitchLog
    UNION ALL
    -- Inserts a new record ( 1, '2016-04-01 00:00:00' ) to the beginning of the day when the first record has Value = 1
    SELECT Value, CONVERT( DATETIME, CONVERT( DATE, LogDate )) AS LogDate
    FROM
        ( SELECT TOP 1 ID, Value, LogDate
        FROM #SwitchLog
        ORDER BY LogDate ASC, ID ASC ) AS DummyRecord --<-- NOTE: the use of a table ID column
    WHERE Value = 1
    UNION ALL
    SELECT Value, LogDate
    FROM #SwitchLog
)
,
Q1 AS (SELECT ROW_NUMBER() OVER (ORDER BY LogDate) AS id,
SUM( Value ) AS Value, LogDate
FROM Q0
GROUP BY LogDate
HAVING COUNT(LogDate) > 1)

SELECT A.Value, DATEDIFF(SECOND,A.LogDate,B.LogDate) AS Total
FROM Q1 AS A
INNER JOIN Q1 AS B
ON B.ID = A.ID + 1 AND B.ID%2 = 0

应使用相同的方法在时段/日+1 00:00:00结束时插入虚拟记录,以适应一天结束时传感器值为1的情况。

您是否在计算关闭和打开之间的秒数?如何打开它,然后再打开?我错过了一些东西。您必须录制多个开关。总共有多少个开关?是的,我想计算在ON和OFF之间的时间,在序列中间的只有开关值为1的行,只有一个开关,当时间戳重复的时候,当开关被切换的时候。我的意思是说现在计数秒和1SI都看到了。你必须在那里做另一个等级才能得到它。“我本来打算采用一种简洁的方法,但没有领会到这一点。@豪尔赫,让我们看看其他人是否可以提交一个更好的答案,如果没有其他问题,请将答案标记为已接受。”。
SELECT 
    Seconds=SUM(X.Seconds)
FROM
(
    SELECT  
        Seconds=DATEDIFF(SECOND,LAG(T1.TimeStamp) OVER (ORDER BY T1.TimeStamp),T1.TimeStamp)    
    FROM
        MyTable T1
        INNER JOIN MyTable T2 ON T2.TimeStamp=T1.TimeStamp AND T1.Value<>T2.Value
    WHERE
        T1.Value=1
)AS X