SQL vs MySQL: Zasady dotyczące operacji agregujących i GROUP BY
Wta książka Obecnie czytam podczas kursu o bazach danych, podany jest następujący przykład nielegalnego zapytania za pomocą operatora agregującego:
Znajdź nazwę i wiek najstarszego żeglarza.
Rozważ następującą próbę odpowiedzi na to zapytanie:
SELECT S.sname, MAX(S.age)
FROM Sailors S
Celem tego zapytania jest zwrócenie nie tylko maksymalnego wieku, ale także nazwy marynarzy mających ten wiek. Jednak to zapytanie jest niedozwolone w SQL - jeśli klauzula SELECT używa operacji agregującej, musi użyćtylko operacje agregujące, chyba że zapytanie zawiera klauzulę GROUP BY!
Jakiś czas później, podczas wykonywania ćwiczenia z wykorzystaniem MySQL, spotkałem się z podobnym problemem i popełniłem błąd podobny do wspomnianego. Jednak MySQL nie narzekał i po prostu wypluł kilka tabel, które później okazały się nie to, czego potrzebowałem.
Czy zapytanie powyżej jest naprawdę nielegalne w SQL, ale legalne w MySQL, a jeśli tak, to dlaczego? W jakiej sytuacji należałoby wykonać takie zapytanie?
Dalsze opracowanie pytania:
Pytanie nie dotyczy tego, czy wszystkie atrybuty wymienione w SELECT powinny być również wymienione w GROUP BY. Chodzi o to, dlaczego powyższe zapytanie, używając atrybutów razem z operacjami agregującymi na atrybutach, bez GROUP BY jest legalne w MySQL.
Załóżmy, że tabela Sailors wyglądała tak:
+----------+------+
| sname | age |
+----------+------+
| John Doe | 30 |
| Jane Doe | 50 |
+----------+------+
Zapytanie następnie powróci:
+----------+------------+
| sname | MAX(S.age) |
+----------+------------+
| John Doe | 50 |
+----------+------------+
Kto by tego potrzebował? John Doe nie ma 50 lat, ma 30 lat! Jak stwierdzono w cytacie z książki, jest to pierwsza próba uzyskania imienia i wieku najstarszego marynarza, w tym przykładzie Jane Doe w wieku 50 lat.
SQL powiedziałby, że to zapytanie jest nielegalne, ale MySQL kontynuuje i wypluwa „śmieci”. Kto będzie potrzebował tego rodzaju wyników? Dlaczego MySQL dopuszcza tę małą pułapkę dla nowicjuszy?