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

Bryder MySQL standarden ved at tillade at vælge kolonner, der ikke er en del af group by-klausulen?

Standard SQL ville afvise din forespørgsel, fordi du ikke kan VÆLGE ikke-samlede felter som ikke er en del af GROUP BY-sætningen i en samlet forespørgsel

Dette er korrekt, indtil 1992 .

Men det er klart forkert, fra 2003 og frem.

Fra SQL-2003 standard, 6IWD6-02-Foundation-2011-01.pdf, fra http ://www.wiscorp.com/ , afsnit 7.12 (forespørgselsspecifikation), side 398 :

  1. Hvis T er en grupperet tabel, så lad G være sættet af grupperingskolonner af T. I hver ((værdiudtryk)) indeholdt i ((vælg liste)), skal hver kolonnehenvisning, der refererer til en kolonne med T, henvise til nogle kolonne C, der er funktionelt afhængig på G eller skal være indeholdt i et aggregeret argument af en ((indstil funktionsspecifikation)), hvis aggregeringsforespørgsel er QS

Nu har MYSQL implementeret denne funktion ved at tillade ikke kun kolonner, der er funktionelt afhængige på grupperingskolonnerne men tillader alle kolonner . Dette forårsager nogle problemer med brugere, der ikke forstår, hvordan gruppering fungerer og får ubestemte resultater, hvor de ikke forventer.

Men du har ret i at sige, at MySQL har tilføjet en funktion, der er i konflikt med SQL-standarder (selvom du synes at tro det af den forkerte grund). Det er ikke helt nøjagtigt, da de har tilføjet en SQL-standardfunktion, men ikke på den bedste måde (mere som den nemme måde), men det er i modstrid med de nyeste standarder.

For at besvare dit spørgsmål, er årsagen til denne MySQL-funktion (udvidelse) jeg formoder, at den er i overensstemmelse med de nyeste SQL-standarder (2003+). Hvorfor de valgte at implementere det på denne måde (ikke fuldt ud kompatibelt), kan vi kun spekulere på.

Som @Quassnoi og @Johan svarede med eksempler, er det primært et problem med ydeevne og vedligeholdelse. Men man kan ikke nemt ændre RDBMS til at være klog nok (ekskluderet Skynet) til at genkende funktionelt afhængige kolonner, så MySQL-udviklere tog et valg:

Vi (MySQL) giver dig (MySQL-brugere) denne funktion, som er i SQL-2003-standarder. Det forbedrer hastigheden i visse GROUP BY forespørgsler, men der er en hage. Du skal være forsigtig (og ikke SQL-motoren) så kolonner i SELECT og HAR lister er funktionelt afhængige af GROUP BY kolonner. Hvis ikke, kan du få ubestemmelige resultater.

Hvis du vil deaktivere det, kan du indstille sql_mode til KUN_FULD_GROUP_BY .

Det hele er i MySQL-dokumenterne:Udvidelser til GRUPPER EFTER (5.5) - dog ikke i ovenstående formulering, men som i dit citat (de glemte endda at nævne, at det er en afvigelse fra standard SQL-2003, mens det ikke er standard SQL-92). Denne form for valg er almindelige, tror jeg i al software, inklusive andre RDBMS. De er lavet til ydeevne, bagudkompatibilitet og en masse andre grunde. Oracle har den berømte '' er det samme som NULL for eksempel og SQL-Server har sikkert også nogle.

Der er også dette blogindlæg af Peter Bouman, hvor MySQL-udvikleres valg forsvares:Afsløring af GROUP BY-myter .

I 2011, som @Mark Byers informeret os i en kommentar (i et relateret spørgsmål på DBA.SE), PostgreSQL 9.1 tilføjede en ny funktion (udgivelsesdato:september 2011) designet til dette formål. Det er mere restriktivt end MySQL's implementering og tættere på standarden.

Senere, i 2015, annoncerede MySQL, at i 5.7-versionen er adfærden forbedret, så den er i overensstemmelse med standarden og faktisk genkender funktionelle afhængigheder (endnu bedre end Postgres-implementeringen). Dokumentationen:MySQL-håndtering af GROUP BY (5.7) og et andet blogindlæg af Peter Bouman:MySQL 5.7.5:GRUPPER EFTER respekterer funktionelle afhængigheder!



  1. Postgresql generere_serie af måneder

  2. Returner det oprindelige frø af en identitetskolonne i SQL Server

  3. Hvilke forskellige typer begrænsninger er tilgængelige i SQL Server - SQL Server / T-SQL vejledning del 50

  4. Udfylder Many2many-feltet (odoo 8)