Odpovědi od @jjclarkson a @davethegr8 jsou blízko, ale nemůžete vložit agregační funkce do klauzule WHERE. Klauzule WHERE se vyhodnocuje pro každý řádek.
Musíte vyhodnotit MAX()
výraz pro každou skupinu, takže musíte použít HAVING
doložka.
Zkuste toto:
SELECT UserID
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';
@MBCook komentuje, že HAVING
může být pomalý. Máte pravdu, nemusí to být úplně nejrychlejší způsob, jak dosáhnout požadovaného výsledku. Ale HAVING
řešení je nejvíce přehledné . Existují situace, kdy má výkon nižší prioritu než přehlednost a udržovatelnost.
Podíval jsem se na výstup EXPLAIN (na MySQL 5.1.30) pro HAVING
řešení:nebyly použity žádné indexy a další poznámky říkaly „Using temporary; Using filesort
,“ což obvykle znamená, že výkon bude slabý.
Zvažte následující dotaz:
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;
Tím se vygeneruje plán optimalizace, který používá index na UserID
a říká:
- a1:"
Using index; Using temporary
" - a2:"
Using where; Distinct
"
."
Nakonec následující dotaz vygeneruje plán optimalizace, který, jak se zdá, nejefektivněji využívá indexy a žádné dočasné tabulky nebo řazení souborů.
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
"
."
Zdá se, že toto má s největší pravděpodobností nejlepší výkon. Je pravda, že v testovací tabulce mám pouze čtyři řádky, takže toto není reprezentativní test.