SQL Reset row_number при изменении значения столбца - PullRequest
0 голосов
/ 14 ноября 2018

Я пытался решить эту проблему, но не смог.Мне нужно узнать, сколько времени сервер недоступен.Вот следующие данные

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 голосов
/ 14 ноября 2018

Это тип проблемы "группа и острова". Если вы можете объединить все спады и последующие действия (если они есть) в одну группу, тогда все остальное - просто агрегация.

И вы можете сделать это, посчитав количество UPs, которые происходят на или после каждой записи. Это простая накопительная сумма, а остальное - агрегация:

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;
0 голосов
/ 14 ноября 2018

Использовать функцию задержки ()

ДЕМО

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
...