Jaka jest różnica między WHERE a HAVING?
Obie klauzule (WHERE i HAVING) służą do filtrowania, ale działają na różnych etapach przetwarzania zapytania — to ważna koncepcja w analitycznym SQL. Aby to zrozumieć, warto poznać logiczną kolejność wykonywania zapytania SQL:
- FROM (pobranie tabel)
- WHERE (filtrowanie pojedynczych wierszy)
- GROUP BY (grupowanie przefiltrowanych wierszy w "kubełki")
- HAVING (filtrowanie całych grup)
- SELECT (wybranie finalnych kolumn i obliczenie wyrażeń)
- ORDER BY (posortowanie finalnych wyników)
WHERE filtruje wiersze PRZED grupowaniem
Klauzula WHERE działa na danych surowych, wiersz po wierszu. Decyduje, które wiersze trafią do etapu grupowania (GROUP BY). Ponieważ WHERE działa przed agregacją, nie można w niej używać funkcji agregujących (np. COUNT() czy AVG()).
Przykład (filtr przed grupowaniem):
... WHERE Status = 'Aktywny' GROUP BY Klasa;(Najpierw odrzuć wszystkich nieaktywnych uczniów, potem grupuj pozostałych po klasach.)
HAVING filtruje grupy PO grupowaniu (działa na funkcjach agregujących)
Klauzula HAVING działa na danych zagregowanych — czyli na wynikach stworzonych przez GROUP BY (na "kubełkach"). Decyduje, które grupy zostaną pokazane w finalnym wyniku. Ponieważ HAVING działa po agregacji, można w niej używać funkcji agregujących — i to jest jej główne zadanie.
Przykład: znajdź klasy, w których średnia ocen jest wyższa niż 4.0. Nie można użyć WHERE AVG(Srednia) > 4.0, ponieważ WHERE działa przed obliczeniem AVG. Najpierw obliczamy średnie dla każdej klasy (GROUP BY), a dopiero potem je filtrujemy (HAVING):
SELECT
Klasa,
AVG(Srednia) AS SredniaKlasy
FROM Uczniowie
GROUP BY Klasa
HAVING AVG(Srednia) > 4.0;
To zapytanie zwróci tylko te klasy (grupy), dla których obliczona średnia przekroczyła 4.0.
Źródło: Lekcja 12 — Filtrowanie grup (HAVING)