SQL-запрос для агрегирования DateDiff больше заданного значения - PullRequest
1 голос
/ 25 января 2010

У меня есть таблица регистрации, используемая для устройства «сердцебиения». У меня есть эти сетевые устройства, которые регистрируются / пульсируют на сервере каждые 10 минут. Мы хотим получить статистику о том, когда они пропустили запланированное время регистрации. У меня есть запрос, который может сделать это для каждого устройства, но мне нужно изменить его для обработки на всех устройствах.

Таблица сердцебиения выглядит следующим образом:

CREATE TABLE [dbo].[DeviceHeartbeat](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [DeviceId] [int] NULL,
    [CheckinTime] [datetime] NULL,
    [Runtime] [int] NULL,
PRIMARY KEY CLUSTERED 
([Id] ASC)) ON [PRIMARY]

Устройство регистрируется на сервере, сервер добавляет строку в эту таблицу со своим Id, CheckinTime и временем выполнения устройства (аппаратное значение, отправленное устройством). Запрос, который у меня сейчас есть, выглядит так:

WITH t AS
(
  SELECT Checkintime, rn = ROW_NUMBER() OVER (ORDER BY Checkintime)
  FROM DeviceHeartbeat
  WHERE DeviceId = 1112
),
x AS
(
  SELECT d = DATEDIFF(MINUTE, t1.Checkintime, t2.Checkintime)
  FROM t AS t1
  INNER JOIN t AS t2
  ON t1.rn = t2.rn - 1
),
y AS
(
  SELECT stats = CASE WHEN d < 10 THEN ' < 10 '
    WHEN d BETWEEN 10 AND 11 THEN '10 - 11 '
    WHEN d BETWEEN 11 AND 12 THEN '11 - 12 '
    ELSE '+12 ' END + ' minutes:'
  FROM x
)
SELECT stats, COUNT(*) FROM y GROUP BY stats;

Этот запрос ограничен одним указанным устройством. Пример результатов выглядит следующим образом:

stats                  
----------------- ---- 
 < 10  minutes:   1536
10 - 11  minutes: 425
11 - 12  minutes: 952
+12  minutes:     160

В идеале, я занимаюсь только более чем 12 минутами регистрации. Итак, я хотел получить список устройств, для которых регистрация прошла более 12 минут, упорядоченная по их количеству. Это позволит мне увидеть топ-10 или 20 устройств с более чем 12-минутным временем регистрации, предупреждая меня о проблемных устройствах. Что-то вроде:

DeviceId   CheckinsOver12Mins
---------- -------------------
1112       160
1108       152
15         114
106        86

Предложения

1 Ответ

2 голосов
/ 25 января 2010

Попробуйте это:

WITH t AS
(
  SELECT Checkintime, DeviceID, rn = ROW_NUMBER() OVER (ORDER BY DeviceID, Checkintime)
  FROM DeviceHeartbeat
),
x AS
(
  SELECT t1.deviceID, d = DATEDIFF(MINUTE, t1.Checkintime, t2.Checkintime)
  FROM t AS t1
  INNER JOIN t AS t2
  ON t1.rn = t2.rn - 1 and t1.DeviceID = t2.DeviceID
),
y AS
(
  SELECT deviceID
  FROM x
  WHERE d > 12
)
select deviceID, count(deviceID) as [Checkins over 12 mins] FROM y GROUP BY deviceID

Примечание: не иметь тестовых данных - не тестировал, возможно, есть опечатки.

Должно быть, y CTE может быть удален и изменен на меньший запрос:

select deviceID, count(deviceID) as [Checkins over 12 mins] 
FROM x 
GROUP BY deviceID
HAVING d > 12
...