As respostas de @jjclarkson e @davethegr8 estão próximas, mas você não pode colocar funções agregadas na cláusula WHERE. A cláusula WHERE é avaliada para cada linha.
Você precisa avaliar o
MAX()
expressão para cada grupo, então você precisa usar um HAVING
cláusula. Tente isto:
SELECT UserID
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';
@MBCook comenta que
HAVING
pode ser lento. Você está certo, pode não ser a maneira mais rápida de produzir o resultado desejado. Mas o HAVING
solução é a mais clara . Há situações em que o desempenho tem prioridade inferior à clareza e manutenção. Eu olhei para a saída EXPLAIN (no MySQL 5.1.30) para o
HAVING
solução:nenhum índice foi usado e as notas extras diziam "Using temporary; Using filesort
", o que geralmente significa que o desempenho será ruim. Considere a seguinte consulta:
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;
Isso gera um plano de otimização que usa um índice em
UserID
e disse:- a1:"
Using index; Using temporary
" - a2:"
Using where; Distinct
"
Por fim, a consulta a seguir gera um plano de otimização que parece usar índices de maneira mais eficaz, sem tabelas temporárias ou classificação de arquivos.
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
"
Isso parece ter o melhor desempenho. É certo que tenho apenas quatro linhas na minha tabela de teste, portanto, este não é um teste representativo.