Requête SQL pour agréger DateDiff supérieure à la valeur donnée
Question
J'ai une table d'enregistrement utilisé pour l'appareil « battements de coeur ». J'ai ces périphériques réseau que l'enregistrement / rythme cardiaque avec le serveur toutes les 10 minutes. Nous statistiques quand ils voulions manquer leur temps d'enregistrement programmé. J'ai une requête qui peut le faire sur une base par appareil, mais j'ai besoin d'être modifié pour gérer l'ensemble des appareils.
Le tableau de rythme cardiaque ressemble à ceci:
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]
Contrôles de l'appareil dans le serveur, le serveur ajoute une ligne de cette table avec son identifiant, le CheckinTime et l'exécution de l'appareil (une valeur de matériel envoyé par le dispositif). La requête Je regarde actuellement comme ceci:
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;
Cette requête est limitée à un seul périphérique spécifié. Exemples de résultats ressemblent à ceci:
stats
----------------- ----
< 10 minutes: 1536
10 - 11 minutes: 425
11 - 12 minutes: 952
+12 minutes: 160
Idéalement, je suis seulement préoccupé par check-ins de plus de 12 minutes. Alors, ce que je voulais était une liste des périphériques qui ont archivages plus de 12 minutes, commandés par leurs chefs d'accusation. Cela me permettra de voir les 10 ou 20 premiers appareils qui ont plus de 12 minutes des temps de check-in, me alerter sur des dispositifs de problème. Quelque chose comme:
DeviceId CheckinsOver12Mins
---------- -------------------
1112 160
1108 152
15 114
106 86
Suggestions?
La solution
Essayez ceci:
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
Note:. Ne pas avoir des données de test - ne pas tester, pourrait avoir des fautes de frappe
Il doit être le CTE y pourrait être supprimé et modifié pour en faire une petite requête:
select deviceID, count(deviceID) as [Checkins over 12 mins]
FROM x
GROUP BY deviceID
HAVING d > 12