MySQL Klauzula GROUP BY i HAVING z przykładami
⚡ Inteligentne podsumowanie
Klauzule SQL GROUP BY i HAVING przekształcają szczegółowe wiersze w raporty podsumowujące. Klauzula GROUP BY łączy wiersze o tych samych wartościach w jeden wiersz na grupę, natomiast klauzula HAVING filtruje te grupy po zastosowaniu funkcji agregujących, takich jak COUNT.

Czym jest klauzula SQL GROUP BY?
Klauzula GROUP BY jest używanym poleceniem SQL grupuj wiersze o tych samych wartościachJest on zapisywany wewnątrz instrukcji SELECT i zwykle jest używany w połączeniu z funkcjami agregującymi w celu generowania raportów podsumowujących z bazy danych.
To właśnie to robi: to podsumowuje dane przechowywane w bazie danych. Zapytania zawierające klauzulę GROUP BY nazywane są zapytaniami grupowanymi i zwracają jeden wiersz dla każdego elementu grupowanego.
Składnia SQL GROUP BY
Teraz, gdy cel klauzuli jest jasny, przyjrzyjmy się składni podstawowego zapytania grupowego.
SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];
TUTAJ
- "Instrukcje SELECT…„to standard” WYBIERZ SQL zapytanie polecenia.
- "GRUPUJ WEDŁUG nazwa_kolumny1„to klauzula, która wykonuje grupęping na podstawie column_name1.
- "[, nazwa_kolumny2, …]„jest opcjonalny i reprezentuje inne nazwy kolumn, gdy grupaping wykonuje się w więcej niż jednej kolumnie.
- "[WARUNEK MAJĄCY]„jest opcjonalny i służy do ograniczenia wierszy objętych klauzulą GROUP BY. Jest podobny do klauzula GDZIE, z tym wyjątkiem, że jest stosowany poping.
Grouping Korzystanie z pojedynczej kolumny
Najszybszym sposobem sprawdzenia efektu klauzuli SQL GROUP BY jest porównanie zapytania niezgrupowanego z zapytaniem zgrupowanym. Zacznij od prostego zapytania, które zwróci wszystkie wpisy dotyczące płci w tabeli members.
SELECT `gender` FROM `members`;
| płeć |
|---|
| Kobieta |
| Kobieta |
| Mężczyzna |
| Kobieta |
| Mężczyzna |
| Mężczyzna |
| Mężczyzna |
| Mężczyzna |
| Mężczyzna |
Zwracanych jest dziewięć wierszy, a każda wartość jest powtarzana. Załóżmy, że chcemy uzyskać unikalne wartości dla płci. Poniższe zapytanie dodaje klauzulę GROUP BY.
SELECT `gender` FROM `members` GROUP BY `gender`;
Wykonanie powyższego skryptu w MySQL Workbench w stosunku do myflixdb daje nam następujące wyniki.
| płeć |
|---|
| Kobieta |
| Mężczyzna |
Zwróć uwagę, że zwrócono tylko dwa wiersze, ponieważ tabela zawiera tylko dwa typy płci. Klauzula GROUP BY zgrupowała wszystkie elementy „Mężczyźni” i zwróciła dla nich jeden wiersz, podobnie jak w przypadku elementów „Kobiety”.
Grouping Korzystanie z wielu kolumn
Grouping W jednej kolumnie jest to często zbyt ogólne, aby utworzyć prawdziwy raport. Funkcja GROUP BY akceptuje listę kolumn rozdzielonych przecinkami, a kombinacja ich wartości definiuje każdą grupę.
Załóżmy, że chcemy uzyskać listę wartości identyfikatorów kategorii filmów i odpowiadających im lat premiery. Przyjrzyjmy się najpierw wynikowi tego prostego zapytania.
SELECT `category_id`, `year_released` FROM `movies`;
| identyfikator_kategorii | rok_wydania |
|---|---|
| 1 | 2011 |
| 2 | 2008 |
| NULL | 2008 |
| NULL | 2010 |
| 8 | 2007 |
| 6 | 2007 |
| 6 | 2007 |
| 8 | 2005 |
| NULL | 2012 |
| 7 | 1920 |
| 8 | NULL |
| 8 | 1920 |
Podświetlone wiersze wskazują, że wynik zawiera duplikaty. Wykonanie tego samego zapytania z klauzulą GROUP BY spowoduje ich usunięcie.
SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;
Wykonanie powyższego skryptu w MySQL Workbench w połączeniu z bazą danych myflixdb daje nam poniższe wyniki.
| identyfikator_kategorii | rok_wydania |
|---|---|
| NULL | 2008 |
| NULL | 2010 |
| NULL | 2012 |
| 1 | 2011 |
| 2 | 2008 |
| 6 | 2007 |
| 7 | 1920 |
| 8 | 1920 |
| 8 | 2005 |
| 8 | 2007 |
Klauzula GROUP BY działa zarówno na category_id, jak i year_released w celu identyfikacji wyjątkowy wiersze. Dwa zduplikowane wiersze dla kategorii 6 w 2007 r. połączyły się w jeden.
Praktyczna zasada: Jeśli identyfikator kategorii jest taki sam, ale rok wydania jest inny, wiersz jest traktowany jako unikatowy. Jeśli identyfikator kategorii i rok wydania są takie same dla więcej niż jednego wiersza, wiersze są duplikatami i wyświetlany jest tylko jeden z nich.
Grouping i funkcje agregujące
Usuwanie duplikatów jest przydatne, ale prawdziwa moc grupyping pojawia się, gdy jest sparowany z funkcje agregująceFunkcja agregująca oblicza jedną wartość dla każdej grupy: COUNT liczy wiersze, SUM dodaje wartości, a AVG, MIN i MAX opisują spread.
Załóżmy, że chcemy poznać łączną liczbę mężczyzn i kobiet w bazie danych. Poniższy skrypt to umożliwia.
SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;
Wykonanie powyższego skryptu w MySQL Workbench i myflixdb dają nam następujące wyniki.
| płeć | LICZBA(`numer_członkostwa`) |
|---|---|
| Kobieta | 3 |
| Mężczyzna | 6 |
Wiersze są grupowane według każdej unikalnej wartości płci, a liczba wierszy w każdej grupie jest zliczana przez funkcję agregującą COUNT. Dziewięć rekordów członkowskich jest łączonych w dwa wiersze podsumowujące.
Ograniczanie wyników zapytania za pomocą klauzuli HAVING
GroupingNie zawsze są potrzebne dla każdego wiersza w tabeli. Czasami raport musi być ograniczony do określonego kryterium, a to właśnie jest zadaniem klauzuli HAVING.
Załóżmy, że chcemy poznać wszystkie lata wydania filmu o identyfikatorze kategorii 8. Poniższy skrypt pozwala osiągnąć ten wynik.
SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;
Wykonanie powyższego skryptu w MySQL Workbench w połączeniu z bazą danych myflixdb daje nam poniższe wyniki.
| identyfikator_filmu | tytuł | dyrektor | rok_wydania | identyfikator_kategorii |
|---|---|---|---|---|
| 9 | Honey mooners | Jana Schultza | 2005 | 8 |
| 5 | Małe dziewczynki tatusia | NULL | 2007 | 8 |
Tylko filmy z identyfikatorem kategorii 8 zostały zachowane na skutek warunku HAVING.
Ostrzeżenie: MySQL W wersjach 5.7 i nowszych tryb ONLY_FULL_GROUP_BY jest domyślnie włączony, a w tym trybie polecenie SELECT * z klauzulą GROUP BY jest odrzucane, ponieważ identyfikator filmu, tytuł i reżyser nie są ani grupowane, ani agregowane. W środowisku produkcyjnym należy jawnie nazwać zgrupowane kolumny, na przykład: WYBIERZ category_id, year_released Z filmów GRUPUJ WEDŁUG category_id, year_released MAJĄC category_id = 8;
GDZIE vs MAJĄC vs GRUPUJ WEDŁUG vs ORDER BY
Początkujący często mieszają te cztery zdania, ponieważ wszystkie one kształtują zbiór wyników. Różnica polega na tym, jeśli chodzi o komunikację i motywację MySQL stosuje się je: WHERE wykonuje się przed grupowaniem wierszy, HAVING wykonuje się po grupowaniu, a ORDER BY wykonuje się na końcu.
| Klauzula | Co to robi | Kiedy działa | Akceptuje funkcje agregacyjne |
|---|---|---|---|
| WHERE | Filtruje pojedyncze wiersze przed jakąkolwiek grupąping. | Przed GROUP BY | Nie |
| GRUPUJ WEDŁUG | Zwija wiersze o tych samych wartościach do jednego wiersza na grupę. | Po GDZIE | Nie dotyczy |
| MAJĄCY | Filtruje grupy utworzone za pomocą polecenia GROUP BY. | Po GROUP BY | Tak, na przykład HAVING COUNT(*) > 2 |
| ZAMÓW PRZEZ | Sortuje wiersze, które przetrwały poprzednie klauzule. | Nazwisko | Tak, alias zbiorczy można sortować |
Praktyczną konsekwencją jest wydajność. Filtrowanie za pomocą WHERE usuwa wiersze przed grupą.ping praca się rozpoczyna, więc warunek, który nie zależy od wyniku zbiorczego, należy do WHERE, a nie do HAVING.
