sql >> Databáze >  >> RDS >> Mysql

Chování MySQL GROUP BY

MySQL vybere řádek libovolně. V praxi běžně používané úložiště MySQL vrací hodnoty z prvního řádek ve skupině s ohledem na fyzické úložiště.

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

Ostatní lidé mají pravdu, že MySQL vám umožňuje spustit tento dotaz, i když má svévolné a potenciálně zavádějící výsledky. Standard SQL a většina ostatních dodavatelů RDBMS tento druh nejednoznačného dotazu GROUP BY zakazuje. Toto se nazývá pravidlo jedné hodnoty :všechny sloupce ve výběrovém seznamu musí být explicitně součástí kritérií GROUP BY nebo uvnitř agregační funkce, např. COUNT() , MAX() , atd.

MySQL podporuje režim SQL ONLY_FULL_GROUP_BY to způsobí, že MySQL vrátí chybu, pokud se pokusíte spustit dotaz, který porušuje standardní sémantiku SQL.

AFAIK, SQLite je jediný další RDBMS, který umožňuje nejednoznačné sloupce ve seskupeném dotazu. SQLite vrací hodnoty z posledního řádek ve skupině:

select * from foo group by category;

6|bar
3|foo

Dokážeme si představit dotazy, které by nebyly nejednoznačné, ale přesto by porušovaly standardní sémantiku SQL.

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

Neexistuje žádný logický způsob, jak by to mohlo vést k nejednoznačným výsledkům. Každý řádek v foo dostane svou vlastní skupinu, pokud GROUP BY primární klíč foo. Jakýkoli sloupec z foo tedy může mít ve skupině pouze jednu hodnotu. Dokonce i připojení k jiné tabulce, na kterou odkazuje cizí klíč ve foo, může mít pouze jednu hodnotu na skupinu, pokud jsou skupiny definovány primárním klíčem foo.

MySQL a SQLite vám důvěřují, že navrhnete logicky jednoznačné dotazy. Formálně musí být každý sloupec ve výběrovém seznamu funkční závislost sloupců v kritériích GROUP BY. Pokud toto nedodržíte, je to vaše chyba. :-)

Standardní SQL je přísnější a neumožňuje některé dotazy, které by mohly být jednoznačný – pravděpodobně proto, že by to bylo pro RDBMS obecně příliš složité.



  1. Implementace převzetí služeb při selhání v MS SQL Server 2017 Standard

  2. Úložiště testovací databáze IRI-Windocks

  3. Propojení nebo import dat ze Salesforce

  4. Obcházení chyby MySQL Při pokusu o uzamčení zjištěno uváznutí; zkuste transakci restartovat