Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds

WHERE kontra HAVING

To pytanie myli wielu skrybów: kiedy używać WHERE, a kiedy HAVING? Oba filtrują dane, ale w zupełnie innym momencie i na innym poziomie. Rozwiążmy tę zagadkę raz na zawsze.

WHERE filtruje wiersze - PRZED grupowaniem

WHERE działa na pojedynczych wierszach, zanim cokolwiek zostanie pogrupowane. Odrzuca zwoje, które nie spełniają warunku:

1SELECT kategoria_id, COUNT(*)
2FROM ksiazki
3WHERE dostepna = 1          -- najpierw odrzuć niedostępne książki
4GROUP BY kategoria_id;

Tu MySQL najpierw wyrzuca wszystkie niedostępne książki, a dopiero potem grupuje i liczy te, które zostały.

HAVING filtruje grupy - PO agregacji

HAVING działa na gotowych grupach, po obliczeniu agregatów. Odrzuca całe grupy, które nie spełniają warunku:

1SELECT kategoria_id, COUNT(*)
2FROM ksiazki
3GROUP BY kategoria_id
4HAVING COUNT(*) > 3;        -- odrzuć grupy mniejsze niż 4 książki

Najważniejsza różnica

| | WHERE | HAVING | |---|-------|--------| | Kiedy działa | przed grupowaniem | po agregacji | | Na czym działa | na pojedynczych wierszach | na grupach | | Funkcje agregujące | NIE może ich użyć | MOŻE ich użyć |

Zasada kciuka: jeśli warunek dotyczy zwykłej kolumny (

dostepna = 1
,
rok_wydania > 2000
) - użyj WHERE. Jeśli warunek dotyczy wyniku agregacji (
COUNT(*) > 3
,
AVG(cena) > 50
) - użyj HAVING.

Oba naraz

Często używamy ich razem - WHERE zawęża dane, HAVING wybiera grupy:

1SELECT kategoria_id, AVG(cena)
2FROM ksiazki
3WHERE dostepna = 1
4GROUP BY kategoria_id
5HAVING AVG(cena) > 40
6ORDER BY AVG(cena) DESC;

To pełna pieśń agregacji: filtruj wiersze, grupuj, filtruj grupy, sortuj. Mistrzowski rozkaz!

Przejdź do CodeWorlds