sql >> Databasteknik >  >> RDS >> Mysql

MySQL GROUP BY beteende

MySQL väljer en rad godtyckligt. I praktiken returnerar vanliga MySQL-lagringsmotorer värdena från den första rad i gruppen, med avseende på den fysiska lagringen.

create table foo (id serial primary key, category varchar(10));

insert into foo (category) values 
  ('foo'), ('foo'), ('foo'), ('bar'), ('bar'), ('bar');

select * from foo group by category;

+----+----------+
| id | category |
+----+----------+
|  4 | bar      |
|  1 | foo      |
+----+----------+

Andra har rätt i att MySQL låter dig köra den här frågan även om den har godtyckliga och potentiellt vilseledande resultat. SQL-standarden, och de flesta andra RDBMS-leverantörer, tillåter inte denna typ av tvetydiga GROUP BY-frågor. Detta kallas Enkelvärdesregeln :alla kolumner i urvalslistan måste uttryckligen vara en del av GROUP BY-kriterierna, eller i en aggregerad funktion, t.ex. COUNT() , MAX() , etc.

MySQL stöder ett SQL-läge ONLY_FULL_GROUP_BY som gör att MySQL returnerar ett fel om du försöker köra en fråga som bryter mot SQL-standardsemantik.

AFAIK, SQLite är den enda andra RDBMS som tillåter tvetydiga kolumner i en grupperad fråga. SQLite returnerar värden från den senaste rad i gruppen:

select * from foo group by category;

6|bar
3|foo

Vi kan föreställa oss frågor som inte skulle vara tvetydiga, men som ändå bryter mot SQL-standardens semantik.

SELECT foo.*, parent_of_foo.* 
FROM foo JOIN parent_of_foo 
  ON (foo.parent_id = parent_of_foo.parent_id) 
GROUP BY foo_id;

Det finns inget logiskt sätt att detta kan ge tvetydiga resultat. Varje rad i foo får sin egen grupp, om vi GRUPPERAR EFTER den primära nyckeln för foo. Så vilken kolumn som helst från foo kan bara ha ett värde i gruppen. Även att gå med i en annan tabell som refereras av en främmande nyckel i foo kan bara ha ett värde per grupp, om grupperna definieras av foos primärnyckel.

MySQL och SQLite litar på att du designar logiskt entydiga frågor. Formellt måste varje kolumn i urvalslistan vara ett funktionellt beroende av kolumnerna i GROUP BY-kriterierna. Om du inte följer detta är det ditt fel. :-)

Standard SQL är mer strikt och tillåter inte vissa frågor som kan vara entydig - troligen för att det skulle vara för komplicerat för RDBMS att vara säker i allmänhet.



  1. En lösning för markörstödet är inte en implementerad funktion för SQL Server Parallel DataWarehousing TDS-fel

  2. Infoga i... Sammanfoga... Välj (SQL-server)

  3. Rails Migration byter kolumn för att använda Postgres-matriser

  4. SQL primär nyckel