Mysql
 sql >> Database >  >> RDS >> Mysql

Seleziona in MySQL dove tutte le righe soddisfano una condizione

Le risposte di @jjclarkson e @davethegr8 sono vicine, ma non puoi inserire funzioni aggregate nella clausola WHERE. La clausola WHERE viene valutata per ogni riga.

Devi valutare MAX() espressione per ogni gruppo, quindi è necessario utilizzare un HAVING clausola.

Prova questo:

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

@MBCook commenta che HAVING può essere lento. Hai ragione, potrebbe non essere il modo più rapido in assoluto per produrre il risultato desiderato. Ma il HAVING la soluzione è la più chiara . Ci sono situazioni in cui le prestazioni hanno una priorità inferiore rispetto a chiarezza e manutenibilità.

Ho esaminato l'output di EXPLAIN (su MySQL 5.1.30) per HAVING soluzione:non sono stati utilizzati indici e le note extra dicevano "Using temporary; Using filesort ", il che di solito significa che le prestazioni saranno scarse.

Considera la seguente query:

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;

Questo genera un piano di ottimizzazione che utilizza un indice su UserID e dice:

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

Infine, la query seguente genera un piano di ottimizzazione che sembra utilizzare gli indici in modo più efficace e non tabelle temporanee o filesort.

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 "

Questo sembra avere le migliori prestazioni. Certo, ho solo quattro righe nella mia tabella di test, quindi questo non è un test rappresentativo.