Lekcje modułu (4/4)
Filtrowanie grup: HAVING
Kiedy już masz wynik dla każdej grupy (poprzednia lekcja), często chcesz to zrobić
zachowaj tylko te grupy, które spełniają warunek: działy z większą liczbą
niż 2 osoby, projekty ze średnim budżetem powyżej 100 tys., użytkownicy z
co najmniej 10 zamówień. Aby to zrobić, WHERE nie wystarczy.
Dlaczego GDZIE nie wystarczy
WHERE filtruje wiersze tabeli przed agregacją. Więc nie widzi
wynik COUNT(*) lub AVG(...): do czasu uruchomienia WHERE, te
wartości nie zostały jeszcze obliczone.
-- ERROR: COUNT(*) doesn't exist yet when WHERE is evaluated
SELECT department_id, COUNT(*) AS count
FROM employees
WHERE COUNT(*) > 2 -- ❌ doesn't work
GROUP BY department_id;Do filtrowania po agregacji służy dedykowana klauzula: HAVING.
Składnia
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM table
GROUP BY grouping_column
HAVING condition_on_aggregate;-- Departments with more than 2 employees:
SELECT department_id, COUNT(*) AS count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 2;HAVING jest dla GROUP BY tym, czym WHERE jest dla FROM: ta sama idea
(„filtr”), ale zastosowano po grupowaniu, łącznie.
Logiczna kolejność zdań
Aby nigdy więcej nie pomylić WHERE i HAVING, pamiętaj o kolejności
SQL mentalnie je wykonuje:
FROM/JOIN— buduje tabelę startową łącząc źródła.WHERE— usuwa wiersze, na których Ci nie zależy.GROUP BY— zbiera pozostałe wiersze w grupy.HAVING— usuwa grupy, na których Ci nie zależy.SELECT— oblicza końcowe kolumny (w tym agregaty).ORDER BY/LIMIT— zmień kolejność i wytnij.
Ważne uwagi:
- w
WHEREmożesz używać tylko kolumn tabeli; - w
HAVINGmożesz użyć kolumn grupujących i agregatów.
-- Classic combo: filter first, group, filter the groups, sort.
SELECT d.name, AVG(e.salary) AS average
FROM employees AS e
JOIN departments AS d ON e.department_id = d.id
WHERE e.hired_on >= '2018-01-01' -- filter rows
GROUP BY d.name
HAVING AVG(e.salary) > 35000 -- filter groups
ORDER BY average DESC;Spróbuj
Dla każdego działu podaj nazwę (departments.name) i liczbę pracowników, ALE tylko w przypadku działów zatrudniających co najmniej 2 pracowników. Dwie kolumny, jeden wiersz na każdy kwalifikujący się dział.
Pokaż wskazówkę
Warunek „co najmniej 2” staje się COUNT(*) >= 2 w HAVING.
Rozwiązanie dostępne po 3 próbach
Przejrzyj ćwiczenie
Pokaż działy (departments.name), których średnie wynagrodzenie przekracza 35000. Uwzględnij tylko pracowników zatrudnionych od 2018 roku. Dwie kolumny: nazwa i średnia. Sortuj według średniej malejąco.
Pokaż wskazówkę
WHERE filtruje wiersze (pracownicy zatrudnieni od 2018 r.), HAVING filtruje grupy (średnia > 35000).
Rozwiązanie dostępne po 3 próbach