2011-12-28 5 views
2

Nous avons un tableau dans notre base de données dans lequel les différents systèmes rapportent avec l'horodatage et les valeurs. Cette table est appelée la table de données. (Je sais, je ne l'ai pas nommé.)Calcul des différences de dates entre les enregistrements

Donc, je suis chargé de parcourir et de trouver les différences de temps entre les rapports pour un système particulier.

Ne sachant pas comment d'autre pour aller à ce sujet, je crée une table temporaire,:

CREATE TABLE #Readings(
    id   INT IDENTITY(1,1) PRIMARY KEY NOT NULL, 
    timestamp  DATETIME 
) 

Puis-je insérer toutes les lectures d'un système particulier:

INSERT INTO #Readings (timestamp) 
SELECT ReadingAt 
FROM data 
WHERE SenId = 3 
ORDER BY ReadingAt 

Enfin, je exécuter ma requête:

select r1.id, r1.timestamp, datediff(second, r1.timestamp, (select r2.timestamp 
from #Readings r2 where r2.id = (r1.id - 1))) 
from #Readings r1 
where id > 1 

mais ce retour:

101 2011-07-14 04:44:05.443 <null> 
102 2011-07-14 04:46:05.443 -120 
103 2011-07-14 04:48:05.447 -120 
104 2011-07-14 04:50:05.447 -120 
105 2011-07-14 04:52:05.447 -120 
106 2011-07-14 04:54:05.45 -120 
107 2011-07-14 04:56:05.45 -120 
108 2011-07-14 04:58:05.45 -120 
109 2011-07-14 05:00:05.45 -120 
110 2011-07-14 05:02:05.453 -120 

Je l'ai fait ce qui suit:

select r1.id, r1.timestamp, (select r2.timestamp from #Readings r2 where r2.id = (r1.id - 1)) 
from #Readings r1 
where id > 1 

qui retourne les dates exactes. Donc, je me demande comment je peux faire ça?

Merci.

+1

Les résultats que vous avez regarder raisonnable pour moi - si vous voulez des valeurs positives, il suffit de changer l'ordre de la seconde et les troisièmes opérandes. Qu'avez-vous * espérer * obtenir? –

+0

Les résultats sont toujours de 120 secondes quelle que soit la plage de temps. C'est pourquoi ils ne sont pas raisonnables. – Thom

+1

Ce qui est réellement la bonne réponse. Oups. Merci de l'avoir signalé. – Thom

Répondre

4

Simplifiez-vous la vie, n'utilisez pas de sous-requêtes!

select 
    r1.id, 
    r1.timestamp, 
    datediff(second, r2.timestamp, r1.timestamp) as TimeBetween 
from 
    #Readings r1 
    left join #Readings r2 on 
     r1.id = r2.id+1 
where 
    r1.id > 1 

Mais pour ce que ça vaut, la première requête est correcte. Votre fonction datediff est l'intervalle entre l'heure de début et l'heure de fin. Ergo, l'heure de début doit être inférieure à l'heure de fin. C'est pourquoi vous obtenez des négatifs.

+0

J'avais pensé à cela à un moment donné, mais pour une raison quelconque, je ne l'ai pas essayé. Quand j'ai essayé tout à l'heure, il est revenu: 2011-07-14 04: 44: 05,443 \t 2011-07-14 04: 46: 05,443 \t -120 2011-07-14 04 : 48: 05.447 \t -120 2011-07-14 04:50:05.447 \t -120 2011-07-14 04: 52: 05,447 \t -120 2011-07-14 04: 54: 05,45 \t -120 2011-07-14 04: 56: 05,45 \t -120 2011-07-14 04: 58: 05,45 \t -120 2011-07-14 05: 00: 05,45 \t -120 2011-07-14 05: 02: 05,453 \t -120 2011-07-14 05: 04: 05.453 \t -120 2011-07-14 05: 06: 05.457 \t -120 2011-07-14 05: 08: 05,507 \t -120 2011-07-14 05: 10: 05,51 \t -120 – Thom

+0

@Thom - Il est préférable de le faire avec un 'JOIN', mais le problème est avec l'ordre des colonnes sur votre 'DATEDIFF', il devrait être l'inverse. Puisque chaque enregistrement de vos données d'exemple est à 2 minutes d'intervalle, le résultat est -120 secondes – Lamak

+0

Oh, et +1 à votre réponse – Lamak

0

Voici comment vous pouvez le faire en une seule requête, sans tables temporaires

SELECT T1.ReadingAt, T2.ReadingAt, 
     datediff(second, T2.ReadingAt, T1.ReadingAt) AS TimeBetween 
FROM (SELECT ROW_NUMBER() OVER (ORDER BY ReadingAt) AS RowNumber, ReadingAt 
     FROM data 
     WHERE SenId = 3) t1 
     INNER JOIN 
     (SELECT ROW_NUMBER() OVER (ORDER BY ReadingAt) AS RowNumber, ReadingAt 
     FROM data 
     WHERE SenId = 3) t2 ON T1.RowNumber = T2.RowNumber + 1 
Questions connexes