列值更改时,SQL重置row_number

时间:2018-11-14 07:12:52

标签: sql sql-server-2017

我一直在尝试解决此问题,但未能解决。我需要获取服务器不可用多长时间的持续时间。这是以下数据

Date  |  Time  |  Address  |  Status
11-14 |  6:32  |  1.1.1.1  |  Down --- Count Start
11-14 |  6:34  |  1.1.1.1  |  Down
11-14 |  6:54  |  1.1.1.1  |  UP
11-14 |  7:20  |  1.1.1.1  |  Down --- Reset Count to 1
11-14 |  7:25  |  1.1.1.1  |  Down
11-14 |  7:30  |  1.1.1.1  |  Up
11-14 |  7:40  |  1.1.1.1  |  Down --- Reset Count to 1
11-14 |  6:35  |  2.2.2.2  |  Down --- Now this is a different counter cause of different IP

我有这个查询

SELECT [date]
  ,[time]
  ,[address]
  ,[ms]
  ,[bytes]
  ,[ttl]
  ,[Status]
  ,COALESCE(lag([Status]) over(order by [time]),'--') [Row]
  INTO #temp
FROM
(
SELECT [date]
  ,[time]
  ,[address]
  ,[ms]
  ,[bytes]
  ,[ttl]
  ,CASE WHEN [status] = 'Success' THEN 'UP' ELSE 'DOWN' END [Status]
 FROM [ESPS].[dbo].[Ping History] p
 INNER JOIN [SuperDashboard].[dbo].[IP_Mapping] i ON i.[IP] = p.address
 WHERE [Date] = CONVERT(Date,GETDATE())
) a

SELECT [date]
  ,[time]
  ,[address]
  ,[ms]
  ,[bytes]
  ,[ttl]
  ,[Status]
FROM
(
SELECT [date]
  ,[time]
  ,[address]
  ,[ms]
  ,[bytes]
  ,[ttl]
  ,[Status]
  ,CASE WHEN [Status] != [Row] THEN 1 ELSE 0 END [row]
FROM #temp
) a WHERE [row] = 1
DROP TABLE #temp

但这仅适用于一个地址,因为当我尝试添加2.2.2.2时,事情变得混乱。理想的输出是获取服务器每次发生停机时的停机时间。我希望有人可以帮助我解决这个问题,或者至少指向我正确的方向。

编辑1:预期输出应为

Date  |  Start DownTime  |  End DownTime  | Address
11-14 |      6:32        |     6:54       | 1.1.1.1
11-14 |      7:20        |     7:30       | 1.1.1.1
11-14 |      7:40        |                | 1.1.1.1
11-14 |      6:35        |                | 2.2.2.2

2 个答案:

答案 0 :(得分:0)

使用lag()函数

DEMO

select *,case when stat='Down' and (prevval='Up' or prevval is null) then 1 else 0 end as val from
(
 select *,lag(stat) over(partition by address order by address) as prevval
 from #temp
)A

输出:

address stat    prevval val
1.1.1.1 Down            1
1.1.1.1 Up      Down    0
1.1.1.1 Down    Up      1
1.1.1.1 Down    Down    0
1.1.1.1 Up      Down    0
1.1.1.1 Down    Up      1
1.1.1.1 Down    Down    0
2.2.2.2 Down            1

答案 1 :(得分:0)

这是“群岛”问题的一种。如果您可以将所有的失败因素和后续行动(如果有的话)组合在一起,那么剩下的就是汇总。

而且,您可以通过计算每条记录上或记录后发生的UP数来做到这一点。这是一个简单的累加和,然后剩下的就是聚合:

select address, date, grp,
       min(case when status = 'DOWN' then time end) as startDown,
       max(case when status = 'UP' then time end) as endUp
from (select t.*,
             sum(case when status = 'UP' then 1 else 0 end) over (partition by address, date order by time desc) as grp
      from t
     ) t
group by address, date, grp;