2010-03-01 11 views
41

J'ai une table qui contient les éléments suivants:Calculer la différence de temps entre deux rangées

DataDate     Value 
2010-03-01 08:31:32.000 100 
2010-03-01 08:31:40.000 110 
2010-03-01 08:31:42.000 95 
2010-03-01 08:31:45.000 101 
.      . 
.      . 
.      . 

J'ai besoin de multiplier la colonne de valeur par la différence de temps entre les lignes actuelles et précédentes et la somme que pour toute la journée .

J'ai actuellement les données mises en place pour venir toutes les 10 secondes, ce qui rend pour une simple conversion dans la requête:

SELECT Sum((Value/6) FROM History WHERE DataDate BETWEEN @startDate and @endDate 

Où @StartDate et @EndDate sont la date d'aujourd'hui à 00:00:00 et 11:59:59 Avant de définir les données à collecter toutes les 10 secondes, elles ont été collectées chaque fois que la valeur a changé. Il n'y a pas d'entrées en double en termes de temps, la différence de temps minimale est de 1 seconde.

Comment puis-je configurer une requête pour obtenir le temps écoulé entre les lignes pour le cas où je ne connais pas l'intervalle de temps entre les lectures?

J'utilise SQL Server 2005.

Répondre

116
WITH rows AS 
     (
     SELECT *, ROW_NUMBER() OVER (ORDER BY DataDate) AS rn 
     FROM mytable 
     ) 
SELECT DATEDIFF(second, mc.DataDate, mp.DataDate) 
FROM rows mc 
JOIN rows mp 
ON  mc.rn = mp.rn - 1 

Dans SQL Server 2012+:

SELECT DATEDIFF(second, pDataDate, dataDate) 
FROM (
     SELECT *, 
       LAG(dataDate) OVER (ORDER BY dataDate) pDataDate 
     FROM rows 
     ) q 
WHERE pDataDate IS NOT NULL 
+1

Damn qui est utile. Je ne me suis pas rendu compte que je pouvais le faire de cette façon, et maintenant je pourrais juste devoir changer quelques questions :) –

+0

J'aime des solutions comme ceci, simple et efficace. – ChandlerPelhams

+0

Awesomeoness, j'aimerais avoir un bouton +10. – vikingsteve

1

Un peu tweak sur la requête de Quassnoi si vous préférez ne pas utiliser un sous-serait:

SELECT 
     DATEDIFF(second, LAG(dataDate) OVER (ORDER BY dataDate), dataDate) 
FROM rows 
WHERE LAG(dataDate) OVER (ORDER BY dataDate) IS NOT NULL 
Questions connexes