Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Czy MySQL łamie standard, pozwalając na wybieranie kolumn, które nie są częścią klauzuli group by?

Standardowy SQL odrzuci Twoje zapytanie, ponieważ nie możesz WYBRAĆ pól niezwiązanych z agregacją które nie są częścią klauzuli GROUP BY w zapytaniu zbiorczym

To jest poprawne, do 1992 .

Ale to po prostu błędne, od 2003 roku i później.

Ze standardu SQL-2003, 6IWD6-02-Foundation-2011-01.pdf, z http ://www.wiscorp.com/ , akapit 7.12 (specyfikacja zapytania), strona 398 :

  1. Jeśli T jest tabelą zgrupowaną, to niech G będzie zbiorem kolumn grupy T. W każdym ((wyrażenie wartości)) zawartym w ((wybierz listę)) każde odwołanie do kolumny, które odwołuje się do kolumny T, powinno odwoływać się do niektórych kolumna C, która jest zależna funkcjonalnie na G lub powinny być zawarte w zagregowanym argumencie ((ustaw specyfikację funkcji)) którego zapytanie agregujące to QS

Teraz MYSQL zaimplementował tę funkcję, umożliwiając nie tylko kolumny, które są zależne funkcjonalnie w kolumnach grupujących ale zezwalanie na wszystkie kolumny . Powoduje to pewne problemy z użytkownikami, którzy nie rozumieją, jak działa grupowanie i uzyskują nieokreślone wyniki tam, gdzie się nie spodziewają.

Ale masz rację, mówiąc, że MySQL dodał funkcję, która jest sprzeczna ze standardami SQL (chociaż wydaje ci się, że to z niewłaściwego powodu). Nie jest to do końca dokładne, ponieważ dodali standardową funkcję SQL, ale nie w najlepszy sposób (bardziej jak w łatwy sposób), ale koliduje z najnowszymi standardami.

Aby odpowiedzieć na twoje pytanie, powodem tej funkcji (rozszerzenia) MySQL jest, jak sądzę, zgodność z najnowszymi standardami SQL (2003+). Dlaczego zdecydowali się wdrożyć go w ten sposób (nie w pełni zgodny), możemy tylko spekulować.

Jak @Quassnoi i @Johan odpowiedzieli na przykładach, jest to głównie problem z wydajnością i konserwacją. Ale nie można łatwo zmienić RDBMS, aby był wystarczająco sprytny (z wyłączeniem Skynet) do rozpoznawania funkcjonalnie zależnych kolumn, więc programiści MySQL dokonali wyboru:

My (MySQL) dajemy Wam (użytkownikom MySQL) tę funkcję, która jest zgodna ze standardami SQL-2003. Poprawia szybkość w niektórych GROUP BY zapytania, ale jest pewien haczyk. Musisz uważać (a nie na silnik SQL), aby kolumny w SELECT i POSIADAJĄC listy są funkcjonalnie zależne od GROUP BY kolumny. Jeśli nie, możesz uzyskać nieokreślone wyniki.

Jeśli chcesz go wyłączyć, możesz ustawić sql_mode do ONLY_FULL_GROUP_BY .

To wszystko w dokumentacji MySQL:Rozszerzenia do GRUPUJ WG (5.5) - choć nie w powyższym sformułowaniu, ale jak w twoim cytacie (zapomnieli nawet wspomnieć, że jest to odstępstwo od standardowego SQL-2003, a nie standardowego SQL-92). Myślę, że ten rodzaj wyborów jest powszechny we wszystkich programach, w tym w innych RDBMS. Zostały stworzone z myślą o wydajności, kompatybilności wstecznej i wielu innych przyczynach. Oracle ma słynny '' jest taki sam jak NULL na przykład SQL-Server prawdopodobnie też ma.

Jest też ten wpis na blogu autorstwa Petera Boumana, w którym broni się wyboru programistów MySQL:Obalanie GRUPY WG mitów .

W 2011 r. jako @Mark Byers poinformował nas w komentarzu (w powiązanym pytaniu na DBA.SE), PostgreSQL 9.1 dodał nową funkcję (data wydania:wrzesień 2011) przeznaczony do tego celu. Jest bardziej restrykcyjna niż implementacja MySQL i bliższa standardowi.

Później, w 2015 roku MySQL ogłosił, że w wersji 5.7 zachowanie zostało ulepszone, aby było zgodne ze standardem i faktycznie rozpoznawało zależności funkcjonalne (nawet lepiej niż implementacja Postgres). Dokumentacja:Obsługa MySQL dla GROUP BY (5.7) oraz kolejny wpis na blogu autorstwa Petera Boumana:MySQL 5.7.5:GRUPA WG szanuje zależności funkcjonalne!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zapytanie SQL do utworzenia bazy danych w MySQL

  2. Jak przekazać parametry do wywołania zwrotnego zapytania mysql w nodejs?

  3. Funkcja MySQL COT() — zwraca cotangens liczby w MySQL

  4. MySQL a PDO

  5. przekonwertuj datę php na format mysql