Отговорите от @jjclarkson и @davethegr8 са близки, но не можете да поставите агрегатни функции в клаузата WHERE. Клаузата WHERE се оценява за всеки ред.
Трябва да оцените MAX()
израз за всяка група, така че трябва да използвате HAVING
клауза.
Опитайте това:
SELECT UserID
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';
@MBCook коментира, че HAVING
може да бъде бавен. Прав сте, може да не е най-бързият начин за постигане на желания резултат. Но HAVING
решението е най-ясното . Има ситуации, при които производителността има по-нисък приоритет от яснотата и поддръжката.
Погледнах изхода EXPLAIN (на MySQL 5.1.30) за HAVING
решение:не бяха използвани индекси, а в допълнителните бележки пишеше "Using temporary; Using filesort
,“, което обикновено означава, че производителността ще бъде слаба.
Помислете за следната заявка:
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;
Това генерира план за оптимизация, който използва индекс на UserID
и казва:
- a1:"
Using index; Using temporary
" - a2:"
Using where; Distinct
"
И накрая, следната заявка генерира план за оптимизация, който изглежда използва индексите най-ефективно и няма временни таблици или сортиране на файлове.
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
"
Това изглежда най-вероятно да има най-добра производителност. Разбира се, имам само четири реда в моята тестова таблица, така че това не е представителен тест.