2013-08-08 14 views
5

Der Gegenstand der Frage ist nicht sehr erklärend, sorry dafür.Sql zu Timediff zwischen zwei Zeilen basierend auf ID finden

Ya so die Frage folgt: Ich habe eine Datenbankstruktur wie unten, wo pk ist Primärschlüssel, ID ist etwas, das für viele Zeilen mehrere ist.

+------+------+---------------------+ 
| pk | id | value    | 
+------+------+---------------------+ 
| 99 | 1 | 2013-08-06 11:10:00 | 
| 100 | 1 | 2013-08-06 11:15:00 | 
| 101 | 1 | 2013-08-06 11:20:00 | 
| 102 | 1 | 2013-08-06 11:25:00 | 
| 103 | 2 | 2013-08-06 15:10:00 | 
| 104 | 2 | 2013-08-06 15:15:00 | 
| 105 | 2 | 2013-08-06 15:20:00 | 
+------+------+---------------------+ 

Was wirklich erhalten ist, müssen, ist, Wertdifferenz zwischen den ersten zwei Reihen (die von Wert bestellt wird) für jede Gruppe (wobei Gruppe von id). So gemäß obige Struktur benötigen I TIMEDIFF (value100, value99) [die für die ID-1-Gruppe ist] und TIMEDIFF (value104, value103) [die für id 2 -Gruppe]

dh Wertdifferenz der Zeit nach Wert geordnet für die ersten zwei Reihen in jeder Gruppe.

Eine Möglichkeit, die ich denken kann, ist durch 3 Self-Joins (oder 3 Unterabfragen), so dass die ersten beiden in 2 von ihnen, und dritte Abfrage Subtrahieren finden. Irgendwelche Vorschläge?

+0

brauchen Sie es in einem einzigen SQL-Befehl? Können Sie (oder möchten Sie) eine gespeicherte Prozedur verwenden? – Barranka

+0

Wird Liebe single sql Lösung – amitchhajer

+0

Just aktualisiert mein Beispiel .. Bitte markieren Sie eine Antwort als Lösung für Ihr Problem .. wenn jemand passt – lordkain

Antwort

0

sieht ein bisschen komisch ... Aber man kann auf diese Weise versuchen

SET @previous = 0; 
SET @temp = 0; 
SET @tempID = 0; 

Above Schritt kann nicht erforderlich sein .. Aber nur um sicher nichts schief geht

SELECT pkid, id, diff, valtemp FROM (
SELECT IF(@previousID = id, @temp := @temp + 1, @temp := 1) occ, @previousID := id, 
TIMEDIFF(`value`, @previous) diff, pk, id, `value`, @previous := `value` 
FROM testtable) a WHERE occ = 2 
zu machen

Demo on sql fiddle

1

versuchen Sie das .. CTE ist ziemlich stark!

WITH CTE AS (
    SELECT 
    value, pk, id, 
    rnk = ROW_NUMBER() OVER (PARTITION BY id order by id DESC) 
    , rownum = ROW_NUMBER() OVER (ORDER BY id, pk) 
    FROM test 
) 
SELECT 
    curr.rnk, prev.rnk, curr.rownum, prev.rownum, curr.pk, prev.pk, curr.id, prev.id, curr.value, prev.value, curr.value - prev.value 
FROM CTE curr 
INNER JOIN CTE prev on curr.rownum = prev.rownum -1 and curr.id = prev.id 
and curr.rnk <=1 
+0

Update-Beispiel auch beitreten auf ID – lordkain

+0

Von den Tags, ich hoffe, die DB verwendet wird MySql und nicht MSSQL. Und CTE wird für MSSQL unterstützt. – Akhil

+0

ja mysql, keine cte. Danke dazwischen wird sicherlich hilfreich für jemand anderes sein. – amitchhajer

Verwandte Themen