Standardní SQL by váš dotaz odmítl, protože nemůžete VYBRAT neagregovaná pole které nejsou součástí klauzule GROUP BY v souhrnném dotazu
To je správné, až do roku 1992 .
Ale je to jasně špatně, od roku 2003 a později.
Ze standardu SQL-2003, 6IWD6-02-Foundation-2011-01.pdf, z http ://www.wiscorp.com/ , odstavec-7.12 (specifikace dotazu), strana 398 :
- Pokud je T seskupená tabulka, pak nechť G je množina seskupujících sloupců T. V každém ((výraz hodnoty)) obsaženém v ((výběr seznamu)) , každý odkaz na sloupec, který odkazuje na sloupec T, bude odkazovat na nějaký sloupec C, který je funkčně závislý na G nebo musí být obsaženo v souhrnném argumentu ((specifikace funkce nastavení)), jehož agregační dotaz je QS
Nyní MYSQL implementoval tuto funkci tím, že umožňuje nejen sloupce, které jsou funkčně závislé ve sloupcích seskupení ale povolení všech sloupců . To způsobuje určité problémy s uživateli, kteří nerozumí tomu, jak seskupování funguje, a získávají neurčité výsledky tam, kde je neočekávají.
Ale máte pravdu, když říkáte, že MySQL přidalo funkci, která je v rozporu se standardy SQL (ačkoli se zdá, že si myslíte, že ze špatného důvodu). Není to úplně přesné, protože přidali funkci standardu SQL, ale ne tím nejlepším způsobem (spíš tím snadným), ale je to v rozporu s nejnovějšími standardy.
Abych odpověděl na vaši otázku, důvodem této funkce MySQL (rozšíření) je, že předpokládám soulad s nejnovějšími standardy SQL (2003+). Proč se rozhodli implementovat tento způsob (ne zcela vyhovující), můžeme jen spekulovat.
Jak odpověděli @Quassnoi a @Johan s příklady, jde hlavně o problém s výkonem a udržovatelností. Ale nelze snadno změnit RDBMS tak, aby byl dostatečně chytrý (vyjma Skynetu), aby rozpoznal funkčně závislé sloupce, takže vývojáři MySQL se rozhodli:
My (MySQL) vám (uživatelům MySQL) poskytujeme tuto funkci, která je ve standardech SQL-2003. Zlepšuje rychlost v určitých
GROUP BY
dotazy, ale má to háček. Musíte být opatrní (a ne SQL engine), takže sloupce vSELECT
aHAVING
seznamy jsou funkčně závislé naGROUP BY
sloupců. Pokud ne, můžete získat neurčité výsledky.
Pokud jej chcete deaktivovat, můžete nastavit
sql_mode
naONLY_FULL_GROUP_BY
.
Vše je v Dokumentech MySQL:Rozšíření pro GROUP BY
(5.5)
- i když ne ve výše uvedeném znění, ale jako ve vaší citaci (dokonce zapomněli zmínit, že je to odchylka od standardního SQL-2003, zatímco ne standardního SQL-92). Tento druh voleb je běžný, myslím, ve všech softwarech, včetně ostatních RDBMS. Jsou vyrobeny z důvodu výkonu, zpětné kompatibility a mnoha dalších důvodů. Oracle má slavný '' is the same as NULL
například a SQL-Server pravděpodobně také nějaké má.
Existuje také tento blogový příspěvek od Petera Boumana, kde je obhajována volba vývojářů MySQL:Odhalení mýtů skupiny GROUP BY .
V roce 2011 jako @Mark Byers informoval nás v komentáři (v související otázce na DBA.SE), PostgreSQL 9.1 přidal novou funkci (datum vydání:září 2011) určené k tomuto účelu. Je restriktivnější než implementace MySQL a blíže standardu.
Později, v roce 2015 MySQL oznámilo, že ve verzi 5.7 je chování vylepšeno, aby odpovídalo standardu a skutečně rozpoznávalo funkční závislosti (dokonce lepší než implementace Postgres). Dokumentace:Zpracování MySQL pro GROUP BY
(5.7)
a další blogový příspěvek od Petera Boumana:MySQL 5.7.5:GROUP BY
respektuje funkční závislosti!