sql >> Databasteknik >  >> RDS >> Mysql

Välj i MySQL där alla rader uppfyller ett villkor

Svaren från @jjclarkson och @davehegr8 är nära, men du kan inte lägga in aggregerade funktioner i WHERE-satsen. WHERE-satsen utvärderas för varje rad.

Du måste utvärdera MAX() uttryck för varje grupp, så du måste använda en HAVING klausul.

Prova detta:

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

@MBCook kommenterar att HAVING kan vara långsam. Du har rätt, det kanske inte är det absolut snabbaste sättet att få det önskade resultatet. Men HAVING lösningen är den mest tydliga . Det finns situationer där prestanda har lägre prioritet än tydlighet och underhållbarhet.

Jag tittade på EXPLAIN-utgången (på MySQL 5.1.30) för HAVING lösning:inga index användes, och de extra anteckningarna sa "Using temporary; Using filesort ," vilket vanligtvis betyder att prestandan blir dålig.

Tänk på följande fråga:

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;

Detta genererar en optimeringsplan som använder ett index på UserID och säger:

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

Slutligen genererar följande fråga en optimeringsplan som verkar använda index mest effektivt och inga tillfälliga tabeller eller filsortering.

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 "

Detta verkar mest sannolikt ha den bästa prestandan. Visserligen har jag bara fyra rader i min testtabell, så det här är inget representativt test.



  1. Hur man installerar MySQL på Windows

  2. Praktisk gräns för SQL-frågans längd (särskilt MySQL)

  3. Hantera lösenord och resurser i Oracle med hjälp av profil

  4. Ändra startvärdet för Django AutoField