sql >> Base de Datos >  >> RDS >> Mysql

Seleccione en MySQL donde todas las filas cumplen una condición

Las respuestas de @jjclarkson y @davethegr8 están cerca, pero no puede colocar funciones agregadas en la cláusula WHERE. La cláusula WHERE se evalúa para cada fila.

Necesitas evaluar el MAX() expresión para cada grupo, por lo que debe usar un HAVING cláusula.

Prueba esto:

SELECT UserID 
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';

@MBCook comenta que HAVING puede ser lento Tiene razón, puede que no sea la forma más rápida de producir el resultado deseado. Pero el HAVING la solución es la más clara . Hay situaciones en las que el rendimiento tiene menor prioridad que la claridad y la facilidad de mantenimiento.

Observé la salida EXPLAIN (en MySQL 5.1.30) para HAVING solución:no se usaron índices, y las notas adicionales decían "Using temporary; Using filesort ", lo que generalmente significa que el rendimiento será deficiente.

Considere la siguiente 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;

Esto genera un plan de optimización que usa un índice en UserID y dice:

  • a1:"Using index; Using temporary "
  • a2:"Using where; Distinct "

Finalmente, la siguiente consulta genera un plan de optimización que parece usar índices de manera más efectiva, y no tablas temporales ni clasificación de archivos.

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 "

Esto parece más probable que tenga el mejor rendimiento. Es cierto que solo tengo cuatro filas en mi tabla de prueba, por lo que esta no es una prueba representativa.