Ответы @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
"
Скорее всего, это будет лучшая производительность. По общему признанию, у меня есть только четыре строки в моей тестовой таблице, так что это не репрезентативный тест.