Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comportement MySQL GROUP BY

MySQL choisit une ligne arbitrairement. En pratique, les moteurs de stockage MySQL couramment utilisés renvoient les valeurs du premier rangée dans le groupe, par rapport au stockage physique.

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

D'autres personnes ont raison de dire que MySQL vous permet d'exécuter cette requête même si elle a des résultats arbitraires et potentiellement trompeurs. La norme SQL et la plupart des autres fournisseurs de SGBDR interdisent ce type de requête GROUP BY ambiguë. C'est ce qu'on appelle la règle à valeur unique :toutes les colonnes de la liste de sélection doivent faire explicitement partie des critères GROUP BY, ou bien à l'intérieur d'une fonction d'agrégation, par ex. COUNT() , MAX() , etc.

MySQL prend en charge un mode SQL ONLY_FULL_GROUP_BY qui fait que MySQL renvoie une erreur si vous essayez d'exécuter une requête qui viole la sémantique standard SQL.

AFAIK, SQLite est le seul autre SGBDR qui autorise les colonnes ambiguës dans une requête groupée. SQLite renvoie les valeurs du dernier ligne dans le groupe :

select * from foo group by category;

6|bar
3|foo

Nous pouvons imaginer des requêtes qui ne seraient pas ambiguës, mais qui violeraient toujours la sémantique 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;

Il n'y a aucun moyen logique que cela puisse produire des résultats ambigus. Chaque ligne de foo obtient son propre groupe, si nous GROUP BY la clé primaire de foo. Ainsi, toute colonne de foo ne peut avoir qu'une seule valeur dans le groupe. Même la jointure à une autre table référencée par une clé étrangère dans foo ne peut avoir qu'une seule valeur par groupe, si les groupes sont définis par la clé primaire de foo.

MySQL et SQLite vous font confiance pour concevoir des requêtes logiquement non ambiguës. Formellement, chaque colonne de la liste de sélection doit être une dépendance fonctionnelle des colonnes dans les critères GROUP BY. Si vous ne respectez pas cela, c'est de votre faute. :-)

Le SQL standard est plus strict et interdit certaines requêtes qui pourraient être sans ambiguïté - probablement parce qu'il serait trop complexe pour que le SGBDR soit sûr en général.