2010-01-25 8 views
1

J'ai une table de journalisation utilisée pour les «pulsations» de périphérique. J'ai ces périphériques réseau qui check-in/heartbeat avec le serveur toutes les 10 minutes. Nous voulons des statistiques sur le moment où ils manqueront leur heure d'enregistrement prévue. J'ai une requête qui peut faire cela sur une base par appareil, mais j'ai besoin d'être modifié pour gérer tous les périphériques.Requête SQL pour agréger DateDiff supérieure à la valeur donnée

Le tableau du 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] 

appareil vérifie dans le serveur, le serveur ajoute une ligne à cette table avec son identifiant, le CheckinTime et l'exécution de l'appareil (une valeur matérielle 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 périphérique spécifié unique. Les résultats de l'exemple ressemblent à ceci:

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

Idéalement, je ne m'intéresse qu'aux check-ins de plus de 12 minutes. Donc, ce que je voulais, c'était une liste d'appareils qui ont des check-ins de plus de 12 minutes, classés par leurs comptes. Cela me permettra de voir les 10 ou 20 premiers appareils qui ont plus de 12 minutes d'enregistrement, m'avertissant des appareils défectueux. Quelque chose comme:

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

Suggestions?

Répondre

2

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 disposer de données de test - ne pas tester, pourrait avoir des fautes de frappe.

Il devrait ê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 
+0

qui fonctionne! Merci beaucoup. –

+0

YW, Mon plaisir. – Hogan

Questions connexes