De antwoorden van @jjclarkson en @davethegr8 zijn dichtbij, maar u kunt geen statistische functies in de WHERE-component plaatsen. De WHERE-component wordt voor elke rij geëvalueerd.
U moet de MAX()
. evalueren uitdrukking voor elke groep, dus u moet een HAVING
. gebruiken clausule.
Probeer dit:
SELECT UserID
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';
@MBCook merkt op dat HAVING
traag kan zijn. Je hebt gelijk, het is misschien niet de absoluut snelste manier om het gewenste resultaat te bereiken. Maar de HAVING
oplossing is de meest duidelijke . Er zijn situaties waarin prestaties een lagere prioriteit hebben dan duidelijkheid en onderhoudbaarheid.
Ik keek naar de EXPLAIN-uitvoer (op MySQL 5.1.30) voor de HAVING
oplossing:er werden geen indexen gebruikt, en de extra opmerkingen zeiden:"Using temporary; Using filesort
," wat meestal betekent dat de prestaties slecht zullen zijn.
Beschouw de volgende vraag:
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;
Dit genereert een optimalisatieplan dat gebruikmaakt van een index op UserID
en zegt:
- a1:"
Using index; Using temporary
" - a2:"
Using where; Distinct
"
Ten slotte genereert de volgende query een optimalisatieplan dat indexen het meest effectief lijkt te gebruiken, en geen tijdelijke tabellen of bestandssortering.
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
"
Dit lijkt het meest waarschijnlijk de beste prestaties te hebben. Toegegeven, ik heb maar vier rijen in mijn testtabel, dus dit is geen representatieve test.