Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wählen Sie in MySQL aus, wo alle Zeilen eine Bedingung erfüllen

Die Antworten von @jjclarkson und @davethegr8 liegen nahe, aber Sie können keine Aggregatfunktionen in die WHERE-Klausel einfügen. Die WHERE-Klausel wird für jede Zeile ausgewertet.

Sie müssen MAX() auswerten Ausdruck für jede Gruppe, also müssen Sie einen HAVING verwenden Klausel.

Versuchen Sie Folgendes:

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

@MBCook kommentiert, dass HAVING kann langsam sein. Sie haben Recht, es ist vielleicht nicht der absolut schnellste Weg, um das gewünschte Ergebnis zu erzielen. Aber das HAVING Lösung ist die klarste . Es gibt Situationen, in denen Leistung weniger Priorität hat als Übersichtlichkeit und Wartbarkeit.

Ich habe mir die EXPLAIN-Ausgabe (auf MySQL 5.1.30) für HAVING angesehen Lösung:Es wurden keine Indizes verwendet, und die zusätzlichen Hinweise lauteten:„Using temporary; Using filesort ," was normalerweise bedeutet, dass die Leistung schlecht ist.

Betrachten Sie die folgende Abfrage:

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;

Dadurch wird ein Optimierungsplan generiert, der einen Index für UserID verwendet und sagt:

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

Schließlich generiert die folgende Abfrage einen Optimierungsplan, der Indizes am effektivsten zu verwenden scheint und keine temporären Tabellen oder Dateisortierung.

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 "

Dies scheint am wahrscheinlichsten die beste Leistung zu haben. Zugegeben, ich habe nur vier Zeilen in meiner Testtabelle, also ist das kein repräsentativer Test.