Funkcje agregujące (ang. aggregate functions) to funkcje, które biorą cały zbiór wierszy, mielą go i zwracają jedną wartość. Zamiast dostać listę pensji wszystkich pracowników, dostajesz jedną liczbę: ich sumę, średnią albo maksimum. W SQL najczęściej spotkasz piątkę klasyków: COUNT (liczy wiersze), SUM (sumuje), AVG (średnia), MIN i MAX (wartość najmniejsza i największa).
Jak to działa
Klucz do zrozumienia: zwykła funkcja działa na jednym wierszu (np. UPPER(name) zamienia tekst w jednej komórce), a funkcja agregująca przetwarza wiele wierszy naraz i skleja je w jeden wynik. Bez dodatkowych warunków pracuje na całej tabeli. Jeśli dorzucisz GROUP BY, baza dzieli dane na grupy i liczy agregat osobno dla każdej z nich — np. średnią pensję per dział.
Ważny szczegół, na którym wszyscy się kiedyś przejechali: większość funkcji agregujących (poza COUNT(*)) ignoruje wartości NULL. AVG(salary) policzy średnią tylko z tych, którzy mają wpisaną pensję — puste pola po prostu nie wejdą do mianownika.
Przykład z praktyki
Masz tabelę orders w PostgreSQL i chcesz wiedzieć, ilu klientów złożyło zamówienia i jaka jest łączna wartość per klient:
SELECT customer_id, COUNT(*) AS liczba, SUM(amount) AS razem FROM orders GROUP BY customer_id HAVING SUM(amount) > 1000;
Zwróć uwagę na HAVING — to filtr na wynikach agregacji. Nie możesz tu użyć WHERE SUM(amount) > 1000, bo WHERE działa na pojedynczych wierszach, zanim cokolwiek się zagreguje. To jedna z najczęstszych pomyłek juniorów.
Częste błędy
- Kolumna spoza GROUP BY w SELECT. Jeśli grupujesz po
customer_id, nie możesz ot tak wyświetlićorder_date— baza nie wie, którą datę z grupy pokazać. PostgreSQL rzuci błędem, a MySQL (zależnie od trybu) po cichu zwróci losowy wiersz, co jest jeszcze gorsze. - Mylenie WHERE z HAVING.
WHEREfiltruje przed agregacją,HAVINGpo niej. - COUNT(*) vs COUNT(kolumna). Pierwszy liczy wszystkie wiersze, drugi pomija NULL-e.
COUNT(DISTINCT kolumna)policzy tylko unikalne wartości.
Pojęcia powiązane: GROUP BY, HAVING, NULL, window functions (jak SUM() OVER() — agregują, ale nie zwijają wierszy), DISTINCT, klauzula SELECT.