Lekcja 11: Grupowanie danych - GROUP BY

Preview Mode

You're viewing this material in preview mode. Sign up to track your progress and access all features.

Lekcja 11: Grupowanie danych - GROUP BY
Required In Progress

Jak używać funkcji agregujących dla podgrup danych?

Problem: Zapytanie z poprzedniej lekcji, np. SELECT AVG(Srednia) FROM Uczniowie;, zwraca średnią dla całej tabeli (całej szkoły). Co zrobić, gdy chcemy otrzymać średnią dla każdej klasy osobno (np. '3A', '3B', '3C') w jednym wyniku? Do tego służy klauzula GROUP BY.

Klauzula GROUP BY — opis działania

Klauzula GROUP BY instruuje bazę danych, aby podzieliła wiersze (po filtrze WHERE, jeśli jest użyty) na grupy na podstawie unikalnych wartości w podanej kolumnie (lub kolumnach). Dla każdej takiej grupy obliczane są następnie funkcje agregujące (np. AVG, COUNT, SUM), zamiast obliczeń dla całej tabeli.

W przykładzie poniżej GROUP BY Klasa tworzy osobną grupę dla wszystkich wierszy, gdzie Klasa = '3A', dla wszystkich z '3B' itd., a następnie liczy średnią i liczbę uczniów dla każdej grupy.

SELECT
  Klasa,
  AVG(Srednia) AS SredniaWKlasie,
  COUNT(*) AS LiczbaUczniow
FROM Uczniowie
GROUP BY Klasa;

Przykładowy wynik:

  • Klasa: '3A' — SredniaWKlasie: 4.15 — LiczbaUczniow: 30
  • Klasa: '3B' — SredniaWKlasie: 3.98 — LiczbaUczniow: 28
  • Klasa: '3C' — SredniaWKlasie: 4.30 — LiczbaUczniow: 31

Uwagi o funkcjach agregujących (COUNT, SUM, AVG) i ich zachowaniu z wartościami NULL są omówione w materiałach o funkcjach agregujących . Z kolei użycie agregacji razem z grupowaniem jest opisane w dalszych lekcjach dotyczących agregacji i GROUP BY .

Reguła SELECT z GROUP BY (najważniejsza zasada)

Główna zasada brzmi: gdy używasz GROUP BY, w klauzuli SELECT możesz umieścić jedynie:

  1. Kolumny, które występują w GROUP BY (np. Klasa),
  2. Funkcje agregujące (np. AVG(Srednia), COUNT(*)).

Dlaczego? Ponieważ zapytanie zwraca po jednym wierszu na grupę. Jeżeli spróbujesz dodać kolumnę, która nie jest ani w GROUP BY, ani agregatem (np. Imie), to baza nie wie, którą wartość z wielu wierszy w danej grupie pokazać i zgłosi błąd.

-- BŁĘDNE zapytanie:
SELECT Imie, Klasa, AVG(Srednia)
FROM Uczniowie
GROUP BY Klasa;
-- Baza nie wie, które Imie pokazać dla grupy (np. '3A'), bo jest tam wiele imion.

Dodatkowe przykłady użycia (praktyczne przypadki)

  • Filtrowanie przed grupowaniem (WHERE):

    SELECT Klasa, AVG(Srednia) AS Srednia
    FROM Uczniowie
    WHERE Rok = 2025
    GROUP BY Klasa;
    

    Najpierw wybieramy tylko uczniów z 2025 roku, potem grupujemy po klasie i liczymy średnie.

  • Grupowanie po kilku kolumnach:

    SELECT Rok, Klasa, AVG(Srednia) AS Srednia
    FROM Uczniowie
    GROUP BY Rok, Klasa;
    

    Tworzy grupy np. dla (Rok=2024, Klasa='3A'), (Rok=2024, Klasa='3B') itd.

  • Użycie HAVING do filtrowania grup:

    SELECT Klasa, AVG(Srednia) AS Srednia, COUNT(*) AS Liczba
    FROM Uczniowie
    GROUP BY Klasa
    HAVING AVG(Srednia) > 4.0 AND COUNT(*) >= 20;
    

    HAVING filtruje już powstałe grupy (np. pokazuje tylko klasy ze średnią > 4.0 i conajmniej 20 uczniów).

  • Porządkowanie wyników:

    SELECT Klasa, AVG(Srednia) AS Srednia
    FROM Uczniowie
    GROUP BY Klasa
    ORDER BY Srednia DESC;
    

    Wyświetla klasy posortowane od najwyższej do najniższej średniej.

  • GROUP BY z COUNT(DISTINCT):

    SELECT Klasa, COUNT(DISTINCT Miasto) AS LiczbaMiast
    FROM Uczniowie
    GROUP BY Klasa;
    

    Liczba różnych miast, z których pochodzą uczniowie danej klasy.

  • GROUP BY z JOIN (grupowanie po kolumnie z tabeli dołączonej):

    SELECT K.NazwaKlasy, AVG(U.Srednia) AS Srednia
    FROM Uczniowie U
    JOIN Klasy K ON U.ID_Klasy = K.ID_Klasy
    GROUP BY K.NazwaKlasy;
    

    Przydatne, gdy nazwa klasy jest trzymana w osobnej tabeli Klasy.

  • Przykład praktyczny: statystyki pojedynczej klasy:

    SELECT
      COUNT(*) AS LiczbaUczniow,
      AVG(Srednia) AS SredniaOcen,
      MAX(Srednia) AS Najwyzsza,
      MIN(Srednia) AS Najnizsza
    FROM Uczniowie
    WHERE Klasa = '3A';
    

    To zapytanie bez GROUP BY zwraca jedną linię ze statystykami dla klasy '3A' (pokazane tu jako alternatywa do grupowania).

Najczęściej popełniane błędy

  • Umieszczanie w SELECT kolumn, które nie są w GROUP BY i nie są agregatami — powoduje błąd logiczny/wyjątek.
  • Mylenie WHERE i HAVING — WHERE filtruje wiersze przed grupowaniem, HAVING filtruje już powstałe grupy.
  • Nieprawidłowe użycie COUNT: pamiętaj, że COUNT(*) liczy wszystkie wiersze, a COUNT(kolumna) zlicza tylko nie-NULL wartości.

Materiały pomocnicze o funkcjach agregujących i grupowaniu można znaleźć w lekcjach dotyczących funkcji agregujących (COUNT, SUM, AVG) oraz MIN/MAX i grupowania .