sql >> Databáze >  >> RDS >> Mysql

Porušuje MySQL standard tím, že umožňuje výběr sloupců, které nejsou součástí skupiny podle klauzule?

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 :

  1. 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 v SELECT a HAVING seznamy jsou funkčně závislé na GROUP BY sloupců. Pokud ne, můžete získat neurčité výsledky.

Pokud jej chcete deaktivovat, můžete nastavit sql_mode na ONLY_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!



  1. SQL, jak mazat data a tabulky

  2. Jak funguje funkce STR() v SQL Server (T-SQL)

  3. Heroku Postgresql s Google Datastudio

  4. Jak vypočítat průměrný prodej za den v MySQL