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

MySQL GROUP BY comportamento

MySQL sceglie una riga arbitrariamente. In pratica, i motori di archiviazione MySQL comunemente usati restituiscono i valori dal primo riga nel gruppo, rispetto alla memoria fisica.

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

Altre persone hanno ragione sul fatto che MySQL ti consente di eseguire questa query anche se ha risultati arbitrari e potenzialmente fuorvianti. Lo standard SQL e la maggior parte degli altri fornitori di RDBMS non consentono questo tipo di query ambigua GROUP BY. Questa è chiamata Regola a valore singolo :tutte le colonne della select-list devono essere esplicitamente parte dei criteri GROUP BY, oppure all'interno di una funzione aggregata, ad es. COUNT() , MAX() , ecc.

MySQL supporta una modalità SQL ONLY_FULL_GROUP_BY ciò fa sì che MySQL restituisca un errore se si tenta di eseguire una query che viola la semantica standard SQL.

AFAIK, SQLite è l'unico altro RDBMS che consente colonne ambigue in una query raggruppata. SQLite restituisce valori dall'ultimo riga nel gruppo:

select * from foo group by category;

6|bar
3|foo

Possiamo immaginare query che non sarebbero ambigue, ma violano comunque la semantica standard 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;

Non c'è un modo logico che questo possa produrre risultati ambigui. Ogni riga in foo ottiene il proprio gruppo, se GROUP BY la chiave primaria di foo. Quindi qualsiasi colonna di foo può avere un solo valore nel gruppo. Anche l'unione a un'altra tabella referenziata da una chiave esterna in foo può avere un solo valore per gruppo, se i gruppi sono definiti dalla chiave primaria di foo.

MySQL e SQLite si affidano a te per progettare query logicamente non ambigue. Formalmente, ogni colonna nell'elenco di selezione deve essere una dipendenza funzionale delle colonne nei criteri GROUP BY. Se non ti attieni a questo, è colpa tua. :-)

L'SQL standard è più rigoroso e non consente alcune query che potrebbero essere inequivocabile, probabilmente perché sarebbe troppo complesso per l'RDBMS per essere sicuro in generale.