Sql 动态计算同一行的时差

Sql 动态计算同一行的时差,sql,sql-server,datediff,availability,Sql,Sql Server,Datediff,Availability,是否有任何方法可以根据“向下”和“向上”值计算同一列中的行之间的SQL时差,如下所示: 有3种情况(我知道): 黄色、橙色和绿色:有一个状态_id 2(向下),之后是状态_id 5(向上),因此需要计算两行之间的时间差 蓝色:存在多个状态_id 2(向下)和之后的一个状态_id 5(向上),因此需要计算第一行和最后一行之间的时差 红色:只有一个状态_id 2(down),因为任何更新都会导致该状态仍然处于down状态,因此需要计算到月底的时差 我希望你能帮助我。我以前做这件事的方式是 Se

是否有任何方法可以根据“向下”和“向上”值计算同一列中的行之间的SQL时差,如下所示:

有3种情况(我知道):

  • 黄色、橙色和绿色:有一个状态_id 2(向下),之后是状态_id 5(向上),因此需要计算两行之间的时间差
  • 蓝色:存在多个状态_id 2(向下)和之后的一个状态_id 5(向上),因此需要计算第一行和最后一行之间的时差
  • 红色:只有一个状态_id 2(down),因为任何更新都会导致该状态仍然处于down状态,因此需要计算到月底的时差

我希望你能帮助我。

我以前做这件事的方式是

Select a.state_time as downtime, 
    (
        select min(inner.state_time) from tablename downentry where
        inner.state_time > outer.state_time and downentry.state='UP'
    ) as uptime

from tablename upentry 
where state = 'DOWN'
然后,您需要找到它们之间的datediff,如果正常运行时间为空,则需要找到停机时间和“endofmonth”之间的datediff


它的性能可能相当差,所以我总是将答案写在数据仓库中,但我认为它给出了您要求的结果。

首先考虑使用它

但使用累积和,MIN的窗口版本也适用于2个以上的DOWN:


SQL2012+

您可以尝试以下解决方案:

SELECT y.group_id, host_id = MIN(host_id), start_time = MIN(state_time), end_time = MAX(state_time), diff_minute = DATEDIFF(MINUTE, MIN(state_time), MAX(state_time))
FROM (
    SELECT *, group_id = SUM(x.new_group_start) OVER(ORDER BY x.host_id, x.state_time)
    FROM (
        SELECT  *, new_group_start = IIF(a.state_id = 'DOWN' AND ISNULL(LAG(a.state_id) OVER(ORDER BY a.host_id, a.state_time), 'UP') = 'UP', 1, 0)
        FROM    @Alerts a
    ) x
) y
GROUP BY y.group_id
ORDER BY y.group_id

您使用的是什么版本的SQL Server?
SELECT y.group_id, host_id = MIN(host_id), start_time = MIN(state_time), end_time = MAX(state_time), diff_minute = DATEDIFF(MINUTE, MIN(state_time), MAX(state_time))
FROM (
    SELECT *, group_id = SUM(x.new_group_start) OVER(ORDER BY x.host_id, x.state_time)
    FROM (
        SELECT  *, new_group_start = IIF(a.state_id = 'DOWN' AND ISNULL(LAG(a.state_id) OVER(ORDER BY a.host_id, a.state_time), 'UP') = 'UP', 1, 0)
        FROM    @Alerts a
    ) x
) y
GROUP BY y.group_id
ORDER BY y.group_id