MySQL wybiera wiersz arbitralnie. W praktyce powszechnie używane silniki pamięci masowej MySQL zwracają wartości z pierwszego wiersz w grupie, w odniesieniu do fizycznej pamięci masowej.
create table foo (id serial primary key, category varchar(10));
insert into foo (category) values
('foo'), ('foo'), ('foo'), ('bar'), ('bar'), ('bar');
select * from foo group by category;
+----+----------+
| id | category |
+----+----------+
| 4 | bar |
| 1 | foo |
+----+----------+
Inni ludzie mają rację, że MySQL pozwala na uruchomienie tego zapytania, mimo że ma arbitralne i potencjalnie mylące wyniki. Standard SQL i większość innych dostawców RDBMS nie zezwala na tego rodzaju niejednoznaczne zapytania GROUP BY. Nazywa się to regułą pojedynczej wartości :wszystkie kolumny na liście wyboru muszą być jawnie częścią kryteriów GROUP BY lub wewnątrz funkcji agregującej, np. COUNT()
, MAX()
itp.
MySQL obsługuje tryb SQL ONLY_FULL_GROUP_BY
to sprawia, że MySQL zwraca błąd, jeśli próbujesz uruchomić zapytanie, które narusza standardową semantykę SQL.
AFAIK, SQLite to jedyny inny RDBMS, który pozwala na niejednoznaczne kolumny w zgrupowanym zapytaniu. SQLite zwraca wartości z ostatniego wiersz w grupie:
select * from foo group by category;
6|bar
3|foo
Możemy sobie wyobrazić zapytania, które nie byłyby niejednoznaczne, ale nadal naruszałyby standardową semantykę SQL.
SELECT foo.*, parent_of_foo.*
FROM foo JOIN parent_of_foo
ON (foo.parent_id = parent_of_foo.parent_id)
GROUP BY foo_id;
Nie ma logicznego sposobu, w jaki mogłoby to spowodować niejednoznaczne wyniki. Każdy wiersz w foo otrzymuje swoją własną grupę, jeśli GRUPUJMY WEDŁUG klucza podstawowego foo. Tak więc każda kolumna z foo może mieć tylko jedną wartość w grupie. Nawet dołączenie do innej tabeli, do której odwołuje się klucz obcy w foo, może mieć tylko jedną wartość na grupę, jeśli grupy są zdefiniowane przez klucz podstawowy foo.
MySQL i SQLite ufają Ci w projektowaniu logicznie jednoznacznych zapytań. Formalnie każda kolumna na liście wyboru musi być zależnością funkcjonalną kolumn w kryteriach GROUP BY. Jeśli tego nie trzymasz, to twoja wina. :-)
Standardowy SQL jest bardziej rygorystyczny i nie zezwala na niektóre zapytania, które mogłyby być jednoznaczne – prawdopodobnie dlatego, że byłoby to zbyt skomplikowane, aby system RDBMS miał ogólnie pewność.