Le risposte di @jjclarkson e @davethegr8 sono vicine, ma non puoi inserire funzioni aggregate nella clausola WHERE. La clausola WHERE viene valutata per ogni riga.
Devi valutare MAX()
espressione per ogni gruppo, quindi è necessario utilizzare un HAVING
clausola.
Prova questo:
SELECT UserID
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';
@MBCook commenta che HAVING
può essere lento. Hai ragione, potrebbe non essere il modo più rapido in assoluto per produrre il risultato desiderato. Ma il HAVING
la soluzione è la più chiara . Ci sono situazioni in cui le prestazioni hanno una priorità inferiore rispetto a chiarezza e manutenibilità.
Ho esaminato l'output di EXPLAIN (su MySQL 5.1.30) per HAVING
soluzione:non sono stati utilizzati indici e le note extra dicevano "Using temporary; Using filesort
", il che di solito significa che le prestazioni saranno scarse.
Considera la seguente query:
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;
Questo genera un piano di ottimizzazione che utilizza un indice su UserID
e dice:
- a1:"
Using index; Using temporary
" - a2:"
Using where; Distinct
"
Infine, la query seguente genera un piano di ottimizzazione che sembra utilizzare gli indici in modo più efficace e non tabelle temporanee o filesort.
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
"
Questo sembra avere le migliori prestazioni. Certo, ho solo quattro righe nella mia tabella di test, quindi questo non è un test rappresentativo.