2010-12-13 16 views
1

Ich habe eine Abfrage, die ich vereinfachen wollen:MySQL - Wie vereinfacht man diese Abfrage?

select 
     sequence, 
     1 added 
     from scoredtable 
     where score_timestamp=1292239056000 
     and sequence 
     not in (select sequence from scoredtable where score_timestamp=1292238452000) 
     union 
select 
     sequence, 
     0 added 
     from scoredtable 
     where score_timestamp=1292238452000 
     and sequence 
     not in (select sequence from scoredtable where score_timestamp=1292239056000); 

Irgendwelche Ideen? Grundsätzlich möchte ich aus der gleichen Tabelle alle Sequenzen extrahieren, die zwischen zwei Timestamp-Werten unterschiedlich sind. Mit einer Spalte "hinzugefügt", die darstellt, ob eine Zeile neu ist oder eine Zeile gelöscht wurde.

Quelltabelle:

score_timestamp    sequence 
1292239056000    0 
1292239056000    1 
1292239056000    2 
1292238452000    1 
1292238452000    2 
1292238452000    3 

Beispiel zwischen (1292239056000, 1292238452000) Abfrageergebnis (2 Zeilen):

sequence added 
3  1 
0  0 

Beispiel zwischen (1292238452000, 1292239056000) Abfrageer (2 Zeilen) :

sequence added 
0  1 
3  0 

Beispiel zwischen (129 2239056000, 1292239056000) Abfrageer (0 Zeilen):

sequence added 

Antwort

2

Diese Abfrage wird alle sequences, das nur einmal innerhalb der beiden Zeitstempel erscheinen, und prüft, ob es zum ersten oder zum zweiten Zeitstempel auftritt.

SELECT 
    sequence, 
    CASE WHEN MIN(score_timestamp) = 1292239056000 THEN 0 ELSE 1 END AS added 
FROM scoredtable 
WHERE score_timestamp IN (1292239056000, 1292238452000) 
    AND (1292239056000 <> 1292238452000) -- No rows, when timestamp is the same 
GROUP BY sequence 
HAVING COUNT(*) = 1 

Es gibt das gewünschte Ergebnis:

sequence added 
3  1 
0  0 
+0

+1 Peter, ich vermisse/vermasselt mein Verständnis davon :) –

+0

großartig! Danke vielmals! –

+0

Hoppla! Es ist nicht die gleiche Frage! Ich habe weitere Beispiele hinzugefügt, die mit dieser Abfrage nicht zufrieden sind :(Zum Beispiel beim Vergleich mit dem gleichen Zeitstempel oder beim Vergleich in der Umkehrreihenfolge (ich möchte auch höher mit niedrigeren Zeitstempeln vergleichen) .... –

0

Gegeben zwei Zeitstempel

SET @ts1 := 1292239056000 
SET @ts2 := 1292238452000 

Sie Ihre Ergänzungen erhalten können und löscht mit:

SELECT s1.sequence AS sequence, 0 as added 
FROM scoredtable s1 LEFT JOIN 
    scoredtable s2 ON 
         s2.score_timestamp = @ts2 AND 
         s1.sequence = s2.sequence 
WHERE 
    s1.score_timestamp = @ts1 AND 
    s2.score_timestampe IS NULL 
UNION ALL 
SELECT s2.sequence, 1 
FROM scoredtable s1 RIGHT JOIN 
    scoredtable s2 ON s1.score_timestamp = @ts1 AND 
         s1.sequence = s2.sequence 
WHERE 
    s2.score_timestamp = @ts2 AND 
    s1.score_timestampe IS NULL 

auf der Anzahl abhängig von Reihen und den Statistikern cs die obige Abfrage könnte besser funktionieren, dann gruppieren mit und mit count (*) = 1 Version (ich denke, dass immer vollständige Tabelle Scan benötigt, während die obige Union in der Lage sein sollte 2 x anti-join, die besser sein könnte)

Wenn Sie wesentliche Daten haben, lassen Sie uns wissen, welche schneller ist (Test mit SQL_NO_CACHE für vergleichbare Ergebnisse)