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

MySQL enfreint-il la norme en autorisant la sélection de colonnes qui ne font pas partie de la clause group by ?

Le SQL standard rejetterait votre requête car vous ne pouvez pas SÉLECTIONNER des champs non agrégés qui ne font pas partie de la clause GROUP BY dans une requête agrégée

C'est correct, jusqu'en 1992 .

Mais c'est complètement faux, depuis 2003 et au-delà.

À partir de la norme SQL-2003, 6IWD6-02-Foundation-2011-01.pdf, à partir de http ://www.wiscorp.com/ , paragraphe-7.12 (spécification de la requête), page 398 :

  1. Si T est un tableau groupé, alors soit G l'ensemble des colonnes de regroupement de T. Dans chaque ((expression de valeur)) contenue dans ((liste de sélection)) , chaque référence de colonne qui référence une colonne de T doit référencer certains la colonne C qui est fonctionnellement dépendante sur G ou doit être contenu dans un argument agrégé d'un ((spécification de la fonction définie))dont la requête d'agrégation est QS

Désormais, MYSQL a implémenté cette fonctionnalité en permettant non seulement colonnes qui sont fonctionnellement dépendantes sur les colonnes de regroupement mais autoriser toutes les colonnes . Cela pose des problèmes aux utilisateurs qui ne comprennent pas le fonctionnement du regroupement et obtiennent des résultats indéterminés là où ils ne s'y attendaient pas.

Mais vous avez raison de dire que MySQL a ajouté une fonctionnalité qui entre en conflit avec les normes SQL (bien que vous sembliez penser cela pour la mauvaise raison). Ce n'est pas tout à fait exact car ils ont ajouté une fonctionnalité standard SQL, mais pas de la meilleure façon (plutôt la manière la plus simple), mais cela entre en conflit avec les dernières normes.

Pour répondre à votre question, la raison de cette fonctionnalité MySQL (extension) est, je suppose, d'être conforme aux dernières normes SQL (2003+). Pourquoi ils ont choisi de l'implémenter de cette façon (pas entièrement conforme), nous ne pouvons que spéculer.

Comme @Quassnoi et @Johan ont répondu avec des exemples, c'est principalement un problème de performances et de maintenabilité. Mais on ne peut pas facilement changer le RDBMS pour qu'il soit assez intelligent (Skynet exclu) pour reconnaître les colonnes fonctionnellement dépendantes, donc les développeurs MySQL ont fait un choix :

Nous (MySQL) vous donnons (utilisateurs de MySQL) cette fonctionnalité qui est dans les normes SQL-2003. Il améliore la vitesse dans certains GROUP BY requêtes mais il y a un hic. Il faut faire attention (et pas le moteur SQL) donc les colonnes dans le SELECT et HAVING les listes dépendent fonctionnellement du GROUP BY Colonnes. Sinon, vous pouvez obtenir des résultats indéterminés.

Si vous souhaitez le désactiver, vous pouvez définir sql_mode à ONLY_FULL_GROUP_BY .

Tout est dans la docs MySQL :extensions de GROUP BY (5.5) - bien que pas dans le libellé ci-dessus mais comme dans votre citation (ils ont même oublié de mentionner qu'il s'agit d'un écart par rapport au standard SQL-2003 alors qu'il ne s'agit pas du standard SQL-92). Ce genre de choix est courant je pense dans tous les logiciels, y compris les autres SGBDR. Ils sont conçus pour la performance, la rétrocompatibilité et bien d'autres raisons. Oracle a le fameux '' is the same as NULL par exemple et SQL-Server en a probablement aussi.

Il y a aussi ce billet de blog de Peter Bouman, où le choix des développeurs MySQL est défendu :Démystifier les mythes GROUP BY .

En 2011, en tant que @Mark Byers nous a informés dans un commentaire (dans une question connexe à DBA.SE), PostgreSQL 9.1 a ajouté une nouvelle fonctionnalité (date de sortie :septembre 2011) conçu à cet effet. Elle est plus restrictive que l'implémentation de MySQL et plus proche de la norme.

Plus tard, en 2015, MySQL a annoncé que dans la version 5.7, le comportement était amélioré pour se conformer à la norme et reconnaître réellement les dépendances fonctionnelles (encore mieux que l'implémentation de Postgres). La documentation :Gestion MySQL de GROUP BY (5.7) et un autre article de blog de Peter Bouman :MySQL 5.7.5 :GROUP BY respecte les dépendances fonctionnelles !