sql >> Databasteknik >  >> RDS >> Mysql

Bryter MySQL mot standarden genom att tillåta att välja kolumner som inte är en del av gruppen för klausul?

Standard SQL skulle avvisa din fråga eftersom du inte kan VÄLJA icke-aggregerade fält som inte ingår i GROUP BY-satsen i en samlad fråga

Detta är rätt, fram till 1992 .

Men det är uppenbart fel, från 2003 och framåt.

Från SQL-2003-standarden, 6IWD6-02-Foundation-2011-01.pdf, från http ://www.wiscorp.com/ , paragraf-7.12 (frågespecifikation), sida 398 :

  1. Om T är en grupperad tabell, låt G vara uppsättningen av grupperingskolumner av T. I varje ((värdeuttryck)) som finns i ((välj lista)) ska varje kolumnreferens som refererar till en kolumn med T referera till några kolumn C som är funktionellt beroende på G eller ska innefattas i ett aggregerat argument av en ((ställ funktionsspecifikation)) vars aggregeringsfråga är QS

Nu har MYSQL implementerat den här funktionen genom att tillåta inte bara kolumner som är funktionellt beroende i grupperingskolumnerna men tillåter alla kolumner . Detta orsakar vissa problem med användare som inte förstår hur gruppering fungerar och som får obestämda resultat där de inte förväntar sig.

Men du har rätt när du säger att MySQL har lagt till en funktion som strider mot SQL-standarder (även om du verkar tro det av fel anledning). Det är inte helt korrekt eftersom de har lagt till en SQL-standardfunktion men inte på det bästa sättet (mer som det enkla sättet), men det strider mot de senaste standarderna.

För att besvara din fråga, anledningen till denna MySQL-funktion (tillägg) är att jag antar att den överensstämmer med de senaste SQL-standarderna (2003+). Varför de valde att implementera det på detta sätt (inte helt kompatibelt) kan vi bara spekulera i.

Som @Quassnoi och @Johan svarade med exempel, är det främst en fråga om prestanda och underhåll. Men man kan inte enkelt ändra RDBMS för att vara tillräckligt smart (Skynet utesluten) för att känna igen funktionellt beroende kolumner, så MySQL-utvecklare gjorde ett val:

Vi (MySQL) ger dig (MySQL-användare) denna funktion som är i SQL-2003-standarder. Det förbättrar hastigheten i vissa GROUP BY frågor men det finns en hake. Du måste vara försiktig (och inte SQL-motorn) så kolumner i SELECT och HAV listor är funktionellt beroende av GROUP BY kolumner. Om inte kan du få obestämda resultat.

Om du vill inaktivera det kan du ställa in sql_mode till ONLY_FULL_GROUP_BY .

Allt finns i MySQL docs:Extensions to GRUPPER EFTER (5.5) - fast inte i ovanstående formulering utan som i ditt citat (de glömde till och med att nämna att det är en avvikelse från standard SQL-2003 men inte standard SQL-92). Den här typen av val är vanliga tror jag i all mjukvara, inklusive andra RDBMS. De är gjorda för prestanda, bakåtkompatibilitet och många andra skäl. Oracle har den berömda '' är samma som NULL till exempel och SQL-Server har förmodligen några också.

Det finns även detta blogginlägg av Peter Bouman, där MySQL-utvecklarnas val försvaras:Avslöja GROUP BY-myter .

2011, som @Mark Byers informerade oss i en kommentar (i en relaterad fråga på DBA.SE), PostgreSQL 9.1 har lagt till en ny funktion (releasedatum:september 2011) designad för detta ändamål. Det är mer restriktivt än MySQL:s implementering och närmare standarden.

Senare, 2015, tillkännagav MySQL att i 5.7-versionen förbättras beteendet för att överensstämma med standarden och faktiskt känna igen funktionella beroenden, (till och med bättre än Postgres-implementeringen). Dokumentationen:MySQL-hantering av GROUP BY (5.7) och ett annat blogginlägg av Peter Bouman:MySQL 5.7.5:GROUP BY respekterar funktionella beroenden!



  1. Vad är skillnaden mellan MyISAM och InnoDB?

  2. Simple Encrypted Arithmetic Library (SEAL) och sigill::Ciphertext-variabeln

  3. Agentavveckling i EM13c

  4. Vilken MySQL-datatyp ska användas för latitud/longitud med 8 decimaler?