Widziałem następujące zapytanie MySQL, które używa jednocześnie DISTINCT i GROUP BY:
SELECT DISTINCT user_id, post_id, post_content FROM some_table GROUP BY post_id, user_id HAVING post_content LIKE "%abc%";
Oto scenariusz towarzyszący zapytaniu: każdy użytkownik ma unikalny identyfikator user_id
i może tworzyć wiele postów, które są identyfikowane za pomocą unikalnego identyfikatora, post_id
. Każdy post zawierałby jakiś tekst.
Wydało mi się to zagmatwane (po przejściu z bazy danych Oracle) i miałem poniższe pytania:
- Jakie jest znaczenie używania
GROUP BY
bez wykonywania jakiejkolwiek agregacji? - Jakie jest znaczenie zmiany kolejności kolumn w
SELECT
w porównaniu zGROUP BY
? - Jakie jest znaczenie pominięcia trzeciej kolumny w
GROUP BY
? - Dlaczego
DISTINCT
używane razem zGROUP BY
? Czy odrębna operacja jest uruchamiana po wykonaniu wszystkich grupowań na wyniku końcowym, czy przed?
Komentarze
Odpowiedź
ad 1) Stare bazy danych mysql i kiedy wyłączysz ONLY_FULL_GROUP_BY , możesz wykonać to zapytanie i jeśli wszystkie post_content są równe, zauważysz, że mysql zwraca losową, nie deterministyczną wartość .
ad 2) none what so ever
ad 3) leniwe programowanie i występuje błąd po włączeniu ONLY_FULL_GROUP_BY
ad 4) Nie, wyświetli wszystkie post_content, które są połączone z user_id, post_id podobnie jak addind post_content do grupy przez
Jak Strawberry już powiedział, że to zapytanie nie ma sens
Odpowiedź
Niesamowita umiejętność zezwalania na częściowe grupowanie według w starszych wersjach MyS QL, musi być jednym z czołowych pretendentów do najczęściej wywoływanego zamieszania w branży IT.
Biorąc pod uwagę tabelę:
CREATE TABLE t ( x int not null primary key , y int not null ); INSERT INTO t (x,y) VALUES (1,1),(1,2);
Oświadczenie
SELECT x, y FROM t GROUP BY x
może oznaczać (1,1) lub (1,2), a MySQL zwróciłby losowo jeden z nich. DISTINCT nie ma znaczenia w tym przypadku, wynik jest nadal niedeterministyczny.
SQL92 wymagał, aby wszystkie kolumny w klauzuli select (z wyjątkiem kolumn zagregowanych i stałych) były częścią klauzuli GROUP BY.
SQL99 poluzował nieco to ograniczenie i pozwolił nam pominąć kolumny z GROUP BY, które są funkcjonalnie zależne od pozostałych kolumn. To znaczy
CREATE TABLE t ( x int not null primary key , y int not null ); SELECT x, y FROM t GROUP by x
byłby prawidłowy, ponieważ y to f.d. z x
Zaskakująco (dla mnie) późniejsza wersja MySQL jest najlepsza w swojej klasie, jeśli chodzi o implementację wersji SQL99. Nie sprawdzałem tego ostatnio, ale kiedy to zrobiłem, MySQL radził sobie dobrze z dość skomplikowanymi scenariuszami, podczas gdy PostgreSQL obsługiwał tylko trywialne.
Aby odpowiedzieć na twoje pytania
1)
SELECT x, y FROM t GROUP BY x, y
oznacza, że kombinacja x, y jest grupą. We wszystkich możliwych sytuacjach przychodzi mi do głowy to samo, co:
SELECT DISTINCT x, y FROM t
Ponieważ są one logicznie oceniane w różnym czasie, może zaistnieć przypadek, w którym faktycznie będą się różnić (chociaż nie mogę wymyślić żadnego)
2) Brak , pod tym względem są zbiorem kolumn, więc nie ma kolejności
3) Patrz wyżej.
4) Logiczna kolejność oceny zapytania SQL to:
FROM, JOIN WHERE GROUP BY HAVING SELECT DISTINCT ORDER BY FETCH FIRST
więc GROUP BY powinno zostać ocenione przed DISTINCT. Nie przychodzi mi do głowy sytuacja, w której miałoby to znaczenie.
W zapytaniu Podejrzewam, że ktoś uzyskał mylące wyniki i próbował uzyskać inny wynik za pomocą narzędzia DISTINCT. Prawdopodobnie miał szczęście (lub pecha), aby uzyskać wynik, oczekiwano, więc DISTINCT został. Błąd nadal istnieje
GROUP BY
w ogóle nie ma znaczenia (z wyjątkiem tego, że w starszych wersjach sugerował to samoORDER BY
.SELECT
kolejność ma znaczenie tylko w układzie kolumn w wynikach.