Các câu trả lời từ @jjclarkson và @ davethegr8 là gần nhau, nhưng bạn không thể đặt các hàm tổng hợp trong mệnh đề WHERE. Mệnh đề WHERE được đánh giá cho mỗi hàng.
Bạn cần đánh giá MAX()
cho mỗi nhóm, vì vậy bạn cần sử dụng HAVING
mệnh đề.
Hãy thử điều này:
SELECT UserID
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';
@MBXem nhận xét HAVING
có thể chậm. Bạn nói đúng, nó có thể không phải là cách nhanh nhất tuyệt đối để tạo ra kết quả mong muốn. Nhưng HAVING
giải pháp là rõ ràng nhất . Có những tình huống mà hiệu suất có mức độ ưu tiên thấp hơn so với độ rõ ràng và khả năng bảo trì.
Tôi đã xem đầu ra EXPLAIN (trên MySQL 5.1.30) cho HAVING
giải pháp:không có chỉ mục nào được sử dụng và ghi chú bổ sung cho biết "Using temporary; Using filesort
, "thường có nghĩa là hiệu suất sẽ kém.
Hãy xem xét truy vấn sau:
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;
Điều này tạo ra một kế hoạch tối ưu hóa sử dụng chỉ mục trên UserID
và nói:
- a1:"
Using index; Using temporary
tạm thời " - a2:"
Using where; Distinct
"
Cuối cùng, truy vấn sau đây tạo ra một kế hoạch tối ưu hóa dường như sử dụng các chỉ mục một cách hiệu quả nhất và không có bảng tạm thời hoặc sắp xếp tệp.
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
"
Điều này dường như có nhiều khả năng có hiệu suất tốt nhất. Phải thừa nhận rằng tôi chỉ có bốn hàng trong bảng thử nghiệm của mình, vì vậy đây không phải là một thử nghiệm đại diện.