sql >> Database >  >> RDS >> Mysql

Breekt MySQL de norm door kolommen te selecteren die geen deel uitmaken van de group by-clausule?

Standaard SQL zou uw zoekopdracht afwijzen omdat u niet-geaggregeerde velden niet kunt SELECTEREN die geen deel uitmaken van de GROUP BY-clausule in een geaggregeerde zoekopdracht

Dit is correct, tot 1992 .

Maar het is duidelijk fout, vanaf 2003 en daarna.

Van SQL-2003-standaard, 6IWD6-02-Foundation-2011-01.pdf, van http ://www.wiscorp.com/ , paragraaf-7.12 (queryspecificatie), pagina 398 :

  1. Als T een gegroepeerde tabel is, laat G dan de verzameling groeperingskolommen van T zijn. In elke ((waarde-uitdrukking)) die is opgenomen in ((selecteer lijst)) , zal elke kolomverwijzing die verwijst naar een kolom van T verwijzen naar een aantal kolom C die functioneel afhankelijk is op G of zal vervat zijn in een geaggregeerd argument van een ((functiespecificatie instellen)) wiens aggregatiequery QS is

Nu heeft MYSQL deze functie geïmplementeerd door niet alleen kolommen die functioneel afhankelijk zijn op de groepeerkolommen maar toestaan ​​van alle kolommen . Dit veroorzaakt problemen bij gebruikers die niet begrijpen hoe groeperen werkt en onbepaalde resultaten krijgen waar ze dat niet verwachten.

Maar je hebt gelijk als je zegt dat MySQL een functie heeft toegevoegd die in strijd is met SQL-standaarden (hoewel je dat om de verkeerde reden lijkt te denken). Het is niet helemaal nauwkeurig omdat ze een SQL-standaardfunctie hebben toegevoegd, maar niet op de beste manier (meer als de gemakkelijke manier), maar het is in strijd met de nieuwste standaarden.

Om je vraag te beantwoorden, ik veronderstel dat de reden voor deze MySQL-functie (extensie) in overeenstemming is met de nieuwste SQL-standaarden (2003+). Waarom ze ervoor hebben gekozen om het op deze manier te implementeren (niet volledig conform), kunnen we alleen maar speculeren.

Zoals @Quassnoi en @Johan antwoordden met voorbeelden, is het vooral een prestatie- en onderhoudbaarheidsprobleem. Maar men kan het RDBMS niet gemakkelijk veranderen om slim genoeg te zijn (Skynet uitgezonderd) om functioneel afhankelijke kolommen te herkennen, dus hebben MySQL-ontwikkelaars een keuze gemaakt:

Wij (MySQL) geven u (MySQL-gebruikers) deze functie die in SQL-2003-standaarden is. Het verbetert de snelheid in bepaalde GROUP BY vragen, maar er is een addertje onder het gras. Je moet voorzichtig zijn (en niet de SQL-engine), dus kolommen in de SELECT en HAVING lijsten zijn functioneel afhankelijk van de GROUP BY kolommen. Als dit niet het geval is, krijgt u mogelijk onbepaalde resultaten.

Als je het wilt uitschakelen, kun je sql_mode . instellen to ONLY_FULL_GROUP_BY .

Het staat allemaal in de MySQL-documenten:Extensies voor GROUP BY (5.5) - hoewel niet in de bovenstaande bewoording, maar zoals in uw citaat (ze zijn zelfs vergeten te vermelden dat het een afwijking is van standaard SQL-2003 terwijl het niet standaard SQL-92 is). Dit soort keuzes is gebruikelijk denk ik in alle software, inclusief andere RDBMS. Ze zijn gemaakt voor prestaties, achterwaartse compatibiliteit en vele andere redenen. Oracle heeft de beroemde '' is the same as NULL bijvoorbeeld en SQL-Server heeft er waarschijnlijk ook een paar.

Er is ook deze blogpost van Peter Bouman, waarin de keuze van MySQL-ontwikkelaars wordt verdedigd:GROUP BY mythen ontkrachten .

In 2011, als @Mark Byers liet ons weten in een opmerking (in een gerelateerde vraag op DBA.SE), PostgreSQL 9.1 heeft een nieuwe functie toegevoegd (releasedatum:september 2011) voor dit doel ontworpen. Het is restrictiever dan de implementatie van MySQL en dichter bij de standaard.

Later, in 2015, kondigde MySQL aan dat in versie 5.7 het gedrag is verbeterd om te voldoen aan de standaard en daadwerkelijk functionele afhankelijkheden te herkennen (zelfs beter dan de Postgres-implementatie). De documentatie:MySQL-verwerking van GROUP BY (5.7) en nog een blogpost van Peter Bouman:MySQL 5.7.5:GROUP BY respecteert functionele afhankelijkheden!



  1. Wat is een logische EN-operator in SQL Server - SQL Server / TSQL-zelfstudiedeel 120

  2. Oracle Date - Hoe jaren tot nu toe toe te voegen

  3. Git-tips en best practices voor beginners

  4. Hoe u de huidige tijd in PostgreSQL kunt krijgen