programowanieAnalityk SQL

Wyjaśnij różnice między HAVING a WHERE w SQL. Do czego służy każdy z nich, jak współdziałają z funkcjami agregującymi i jak unikać powszechnych błędów podczas ich używania?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

WHERE filtruje wiersze przed wykonaniem grupowania i agregacji, a zatem określa, jakie rekordy trafią do grupowania/agregacji. HAVING filtruje grupy już po zastosowaniu funkcji agregujących.

  • WHERE: nie można używać funkcji agregujących (SUM, AVG itp.), ponieważ filtracja odbywa się PRZED grupowaniem.
  • HAVING: można używać funkcji agregujących, ponieważ filtracja odbywa się PO grupowaniu.

Przykład:

-- Uzyskać departamenty z sumą wynagrodzeń większą niż 50000, z wyłączeniem zwolnionych pracowników SELECT department, SUM(salary) as total FROM employees WHERE status = 'active' GROUP BY department HAVING SUM(salary) > 50000;

Tutaj:

  • WHERE status = 'active' — usunie zwolnionych przed obliczeniem sum dla działów;
  • HAVING SUM(salary) > 50000 — pokaże tylko te departamenty, w których łączna pensja przekracza 50000.

Pytanie pułapka

Czy można używać funkcji agregujących w WHERE?

Błąd: próbują napisać WHERE SUM(amount) > 100, ale tak nie można — funkcje agregujące są stosowane TYLKO w HAVING.

Przykład (NIEpoprawnie):

SELECT customer_id, SUM(amount) FROM orders WHERE SUM(amount) > 100 GROUP BY customer_id -- BŁĄD: nieprawidłowe użycie SUM() w WHERE

Poprawnie:

SELECT customer_id, SUM(amount) FROM orders GROUP BY customer_id HAVING SUM(amount) > 100;

Przykłady rzeczywistych błędów z powodu nieznajomości tematu


Historia

Rozwój CRM. Próba filtrowania klientów z liczbą zamówień >5 przez WHERE COUNT(order_id) > 5. Zapytanie nie działało. W rezultacie: liczba klientów w raporcie była niepoprawna, ponieważ COUNT nie można używać w WHERE.


Historia

Analiza biznesowa. Zamiast filtrowania nieaktywnych produktów w WHERE używali HAVING. Wynik: agregowanie "pustych" grup i wolny SQL. Naprawiono przenosząc filtr statusu do WHERE.


Historia

Skomplikowany raport. Użyto HAVING bez GROUP BY do filtrowania pojedynczych wierszy. W niektórych DBMS powoduje to błąd, w innych — nieoczywiste zachowanie. Wniosek: HAVING powinien występować po grupowaniu i dla warunków agregacyjnych.