sql >> Database >  >> RDS >> Mysql

MySQL GROUP BY-gedrag

MySQL kiest willekeurig een rij. In de praktijk retourneren veelgebruikte MySQL-opslagengines de waarden van de eerste rij in de groep, met betrekking tot de fysieke opslag.

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      |
+----+----------+

Andere mensen hebben gelijk dat u met MySQL deze query kunt uitvoeren, ook al heeft deze willekeurige en mogelijk misleidende resultaten. De SQL-standaard en de meeste andere RDBMS-leveranciers staan ​​dit soort dubbelzinnige GROUP BY-query's niet toe. Dit wordt de Single-Value Rule . genoemd :alle kolommen in de selectielijst moeten expliciet deel uitmaken van de GROUP BY-criteria, of anders binnen een aggregatiefunctie, b.v. COUNT() , MAX() , enz.

MySQL ondersteunt een SQL-modus ONLY_FULL_GROUP_BY waardoor MySQL een fout retourneert als u een query probeert uit te voeren die de SQL-standaardsemantiek schendt.

AFAIK, SQLite is de enige andere RDBMS die dubbelzinnige kolommen in een gegroepeerde query toestaat. SQLite retourneert waarden van de laatste rij in de groep:

select * from foo group by category;

6|bar
3|foo

We kunnen ons vragen voorstellen die niet dubbelzinnig zijn, maar toch de semantiek van de SQL-standaard schenden.

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

Er is geen logische manier waarop dit dubbelzinnige resultaten zou kunnen opleveren. Elke rij in foo krijgt zijn eigen groep, als we GROUPEREN OP de primaire sleutel van foo. Dus elke kolom van foo kan maar één waarde in de groep hebben. Zelfs deelnemen aan een andere tabel waarnaar wordt verwezen door een externe sleutel in foo kan slechts één waarde per groep hebben, als de groepen worden gedefinieerd door de primaire sleutel van foo.

MySQL en SQLite vertrouwen erop dat u logisch ondubbelzinnige queries ontwerpt. Formeel moet elke kolom in de selectielijst een functionele afhankelijkheid zijn van de kolommen in de GROUP BY-criteria. Als u zich hier niet aan houdt, is dat uw schuld. :-)

Standaard SQL is strenger en verbiedt sommige zoekopdrachten die zou kunnen wees ondubbelzinnig -- waarschijnlijk omdat het te complex zou zijn voor het RDBMS om in het algemeen zeker te zijn.



  1. Een web-app vanaf nul maken met Python Flask en MySQL:deel 4

  2. PostgreSQL:een berekende kolom gebruiken in dezelfde query

  3. Proactieve SQL Server-statuscontroles, deel 3:instantie- en database-instellingen

  4. Scalaire UDF-inlining in SQL Server 2019