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

MySQL GROUP BY adfærd

MySQL vælger en række vilkårligt. I praksis returnerer almindeligt anvendte MySQL-lagringsmotorer værdierne fra den første række i gruppen med hensyn til det fysiske lager.

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

Andre folk har ret i, at MySQL giver dig mulighed for at køre denne forespørgsel, selvom den har vilkårlige og potentielt vildledende resultater. SQL-standarden og de fleste andre RDBMS-leverandører tillader ikke denne form for tvetydige GROUP BY-forespørgsler. Dette kaldes Enkeltværdi-reglen :alle kolonner i udvælgelseslisten skal være eksplicit en del af GROUP BY-kriterierne, ellers inde i en aggregeret funktion, f.eks. COUNT() , MAX() osv.

MySQL understøtter en SQL-tilstand ONLY_FULL_GROUP_BY der får MySQL til at returnere en fejl, hvis du forsøger at køre en forespørgsel, der overtræder SQL standard semantik.

AFAIK, SQLite er den eneste anden RDBMS, der tillader tvetydige kolonner i en grupperet forespørgsel. SQLite returnerer værdier fra sidste række i gruppen:

select * from foo group by category;

6|bar
3|foo

Vi kan forestille os forespørgsler, der ikke ville være tvetydige, men som alligevel overtræder 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;

Der er ingen logisk måde, hvorpå dette kan give tvetydige resultater. Hver række i foo får sin egen gruppe, hvis vi GRUPPER EFTER den primære nøgle i foo. Så enhver kolonne fra foo kan kun have én værdi i gruppen. Selv tilslutning til en anden tabel refereret af en fremmednøgle i foo kan kun have én værdi pr. gruppe, hvis grupperne er defineret af foo's primære nøgle.

MySQL og SQLite stoler på, at du designer logisk entydige forespørgsler. Formelt skal hver kolonne i valglisten være en funktionel afhængighed af kolonnerne i GROUP BY-kriterierne. Hvis du ikke overholder dette, er det din skyld. :-)

Standard SQL er mere streng og tillader ikke nogle forespørgsler, der kunne være utvetydig - sandsynligvis fordi det ville være for komplekst for RDBMS at være sikker generelt.



  1. SQLite JSON_SET()

  2. Forringes SQLite-ydeevnen, hvis databasestørrelsen er større end 2 gigabyte?

  3. SQL:søg efter en streng i hver varchar-kolonne i en database

  4. Slet sql-rækker, hvor ID'er ikke matcher fra en anden tabel