Odpowiedzi z @jjclarkson i @davethegr8 są bliskie, ale nie możesz umieścić funkcji agregujących w klauzuli WHERE. Klauzula WHERE jest oceniana dla każdego wiersza.
Musisz ocenić MAX() wyrażenie dla każdej grupy, więc musisz użyć HAVING klauzula.
Spróbuj tego:
SELECT UserID
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';
@MBCook komentarze, które HAVING może być powolny. Masz rację, może to nie być absolutnie najszybszy sposób na uzyskanie pożądanego rezultatu. Ale HAVING rozwiązanie jest jasne . Są sytuacje, w których wydajność ma niższy priorytet niż przejrzystość i łatwość konserwacji.
Spojrzałem na wyjście EXPLAIN (w MySQL 5.1.30) dla HAVING rozwiązanie:nie użyto żadnych indeksów, a dodatkowe uwagi mówiły „Using temporary; Using filesort ”, co zwykle oznacza, że wydajność będzie niska.
Rozważ następujące zapytanie:
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;
Spowoduje to wygenerowanie planu optymalizacji, który używa indeksu na UserID i mówi:
- a1:"
Using index; Using temporary - a2:"
Using where; Distinct"
Na koniec następująca kwerenda generuje plan optymalizacji, który wydaje się najefektywniej wykorzystywać indeksy, bez tabel tymczasowych ani sortowania plików.
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”
Wydaje się, że najprawdopodobniej będzie to miało najlepszą wydajność. Muszę przyznać, że w mojej tabeli testowej są tylko cztery wiersze, więc nie jest to test reprezentatywny.