Die Antworten von @jjclarkson und @davethegr8 liegen nahe, aber Sie können keine Aggregatfunktionen in die WHERE-Klausel einfügen. Die WHERE-Klausel wird für jede Zeile ausgewertet.
Sie müssen MAX()
auswerten Ausdruck für jede Gruppe, also müssen Sie einen HAVING
verwenden Klausel.
Versuchen Sie Folgendes:
SELECT UserID
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';
@MBCook kommentiert, dass HAVING
kann langsam sein. Sie haben Recht, es ist vielleicht nicht der absolut schnellste Weg, um das gewünschte Ergebnis zu erzielen. Aber das HAVING
Lösung ist die klarste . Es gibt Situationen, in denen Leistung weniger Priorität hat als Übersichtlichkeit und Wartbarkeit.
Ich habe mir die EXPLAIN-Ausgabe (auf MySQL 5.1.30) für HAVING
angesehen Lösung:Es wurden keine Indizes verwendet, und die zusätzlichen Hinweise lauteten:„Using temporary; Using filesort
," was normalerweise bedeutet, dass die Leistung schlecht ist.
Betrachten Sie die folgende Abfrage:
SELECT DISTINCT a1.UserID
FROM ArrivalTimes a1
LEFT OUTER JOIN ArrivalTimes a2
ON (a1.UserID = a2.UserID AND a2.ArrivalTime > '09:00:00')
WHERE a2.UserID IS NULL;
Dadurch wird ein Optimierungsplan generiert, der einen Index für UserID
verwendet und sagt:
- a1:"
Using index; Using temporary
" - a2:"
Using where; Distinct
"
Schließlich generiert die folgende Abfrage einen Optimierungsplan, der Indizes am effektivsten zu verwenden scheint und keine temporären Tabellen oder Dateisortierung.
SELECT DISTINCT a1.UserID
FROM ArrivalTimes a1
WHERE NOT EXISTS (SELECT * FROM ArrivalTimes a2
WHERE a1.UserID = a2.UserID
AND a2.ArrivalTime > '09:00:00');
- a1:"
Using where; Using index
" - a2:"
Using where
"
Dies scheint am wahrscheinlichsten die beste Leistung zu haben. Zugegeben, ich habe nur vier Zeilen in meiner Testtabelle, also ist das kein repräsentativer Test.