Svaren från @jjclarkson och @davehegr8 är nära, men du kan inte lägga in aggregerade funktioner i WHERE-satsen. WHERE-satsen utvärderas för varje rad.
Du måste utvärdera MAX()
uttryck för varje grupp, så du måste använda en HAVING
klausul.
Prova detta:
SELECT UserID
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';
@MBCook kommenterar att HAVING
kan vara långsam. Du har rätt, det kanske inte är det absolut snabbaste sättet att få det önskade resultatet. Men HAVING
lösningen är den mest tydliga . Det finns situationer där prestanda har lägre prioritet än tydlighet och underhållbarhet.
Jag tittade på EXPLAIN-utgången (på MySQL 5.1.30) för HAVING
lösning:inga index användes, och de extra anteckningarna sa "Using temporary; Using filesort
," vilket vanligtvis betyder att prestandan blir dålig.
Tänk på följande fråga:
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;
Detta genererar en optimeringsplan som använder ett index på UserID
och säger:
- a1:"
Using index; Using temporary
" - a2:"
Using where; Distinct
"
Slutligen genererar följande fråga en optimeringsplan som verkar använda index mest effektivt och inga tillfälliga tabeller eller filsortering.
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
"
Detta verkar mest sannolikt ha den bästa prestandan. Visserligen har jag bara fyra rader i min testtabell, så det här är inget representativt test.