Jawaban dari @jjclarkson dan @davethegr8 sudah dekat, tetapi Anda tidak dapat menempatkan fungsi agregat di klausa WHERE. Klausa WHERE dievaluasi untuk setiap baris.
Anda perlu mengevaluasi MAX()
ekspresi untuk setiap grup, jadi Anda perlu menggunakan HAVING
klausa.
Coba ini:
SELECT UserID
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';
@MBCook berkomentar bahwa HAVING
bisa lambat. Anda benar, ini mungkin bukan cara tercepat mutlak untuk menghasilkan hasil yang diinginkan. Tapi HAVING
solusi yang paling jelas . Ada situasi di mana kinerja memiliki prioritas lebih rendah daripada kejelasan dan pemeliharaan.
Saya melihat output EXPLAIN (pada MySQL 5.1.30) untuk HAVING
solusi:tidak ada indeks yang digunakan, dan catatan tambahan mengatakan "Using temporary; Using filesort
," yang biasanya berarti kinerja akan buruk.
Perhatikan pertanyaan berikut:
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;
Ini menghasilkan rencana pengoptimalan yang menggunakan indeks pada UserID
dan berkata:
- a1:"
Using index; Using temporary
" - a2:"
Using where; Distinct
"
Terakhir, kueri berikut menghasilkan rencana pengoptimalan yang tampaknya menggunakan indeks paling efektif, dan tidak ada tabel sementara atau pengurutan file.
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
"
Ini tampaknya paling mungkin memiliki kinerja terbaik. Memang, saya hanya memiliki empat baris di tabel pengujian saya, jadi ini bukan tes yang representatif.