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.