Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Selecione no MySQL onde todas as linhas atendem a uma condição


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.