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

MySQL sta infrangendo lo standard consentendo la selezione di colonne che non fanno parte della clausola group by?

L'SQL standard rifiuterebbe la tua query perché non puoi SELEZIONARE campi non aggregati che non fanno parte della clausola GROUP BY in una query aggregata

Questo è corretto, fino al 1992 .

Ma è chiaramente sbagliato, dal 2003 in poi.

Dallo standard SQL-2003, 6IWD6-02-Foundation-2011-01.pdf, da http ://www.wiscorp.com/ , paragrafo-7.12 (specifica della query), pagina 398 :

  1. Se T è una tabella raggruppata, allora sia G l'insieme delle colonne di raggruppamento di T. In ciascuna ((espressione valore)) contenuta in ((seleziona elenco)) , ogni riferimento di colonna che fa riferimento a una colonna di T deve fare riferimento ad alcuni colonna C che è funzionalmente dipendente su G o deve essere contenuto in un argomento aggregato di un ((specifica funzione set)) la cui query di aggregazione è QS

Ora MySQL ha implementato questa funzionalità consentendo non solo colonne che sono funzionalmente dipendenti nelle colonne di raggruppamento ma consentendo tutte le colonne . Questo sta causando alcuni problemi agli utenti che non capiscono come funziona il raggruppamento e ottengono risultati indeterminati dove non si aspettano.

Ma hai ragione a dire che MySQL ha aggiunto una funzionalità che è in conflitto con gli standard SQL (anche se sembri pensarlo per la ragione sbagliata). Non è del tutto accurato in quanto hanno aggiunto una funzionalità standard SQL ma non nel migliore dei modi (più simile al modo più semplice), ma è in conflitto con gli standard più recenti.

Per rispondere alla tua domanda, il motivo di questa funzione MySQL (estensione) è suppongo che sia conforme agli ultimi standard SQL (2003+). Perché abbiano scelto di implementarlo in questo modo (non completamente conforme), possiamo solo ipotizzare.

Come @Quassnoi e @Johan hanno risposto con esempi, è principalmente un problema di prestazioni e manutenibilità. Ma non è possibile modificare facilmente l'RDBMS in modo che sia abbastanza intelligente (escluso Skynet) da riconoscere le colonne funzionalmente dipendenti, quindi gli sviluppatori MySQL hanno fatto una scelta:

Noi (MySQL) ti offriamo (utenti MySQL) questa funzionalità che è negli standard SQL-2003. Migliora la velocità in alcuni GROUP BY domande ma c'è un problema. Devi stare attento (e non al motore SQL) quindi colonne in SELECT e HAVING gli elenchi dipendono funzionalmente da GROUP BY colonne. In caso contrario, potresti ottenere risultati indeterminati.

Se vuoi disabilitarlo, puoi impostare sql_mode a ONLY_FULL_GROUP_BY .

È tutto nei Documenti MySQL:estensioni a GROUP BY (5.5) - anche se non nella formulazione sopra ma come nella tua citazione (si sono persino dimenticati di menzionare che è una deviazione dallo standard SQL-2003 mentre non lo standard SQL-92). Questo tipo di scelte è comune a tutti i software, inclusi altri RDBMS. Sono realizzati per prestazioni, compatibilità con le versioni precedenti e molti altri motivi. Oracle ha il famoso '' is the same as NULL per esempio e probabilmente anche SQL-Server ne ha alcuni.

C'è anche questo post sul blog di Peter Bouman, in cui viene difesa la scelta degli sviluppatori MySQL:Debunking GROUP BY miti .

Nel 2011, come @Mark Byers ci ha informato in un commento (in una domanda correlata su DBA.SE), PostgreSQL 9.1 ha aggiunto una nuova funzionalità (data di rilascio:settembre 2011) progettato per questo scopo. È più restrittivo dell'implementazione di MySQL e più vicino allo standard.

Successivamente, nel 2015 MySQL ha annunciato che nella versione 5.7, il comportamento è stato migliorato per conformarsi allo standard e riconoscere effettivamente le dipendenze funzionali (anche meglio dell'implementazione di Postgres). La documentazione:Gestione MySQL di GROUP BY (5.7) e un altro post sul blog di Peter Bouman:MySQL 5.7.5:GROUP BY rispetta le dipendenze funzionali!