Przypomnienie przed Zadaniami 3–6)
- WHERE vs HAVING
•WHEREfiltruje pojedyncze wiersze przed grupowaniem.
•HAVINGfiltruje całe grupy już poGROUP BYi agregacjach.
• Praktyka: warunki nieagregujące (np. konkretna kategoria/miasto) →WHERE; warunki na wynikach agregacji (np. średnia/suma/liczba) →HAVING. - GROUP BY – co musi być w grupowaniu
• Wszystkie kolumny niewyliczane agregacją powinny być wGROUP BY.
• W MySQL zwykle warto trzymać się zasady „albo agregat, albo w GROUP BY” (nie polegaj na luźnej tolerancji). - ORDER BY po aliasie
• Po wyliczeniu agregatu nadaj alias i sortuj po nim, np.AVG(p.cena) AS srednia_cena … ORDER BY srednia_cena DESC. To czytelne i unika powtórzeń. - DISTINCT i COUNT(DISTINCT …)
•DISTINCTusuwa duplikaty.
•COUNT(DISTINCT kolumna)liczy różne wartości w grupie (przyda się np. przy zliczaniu różnych produktów/kategorii na klienta). - JOIN i filtrowanie dat
• Do łączenia tabel używaj jawnychJOINz warunkami ON.
• Zakres dat: w naszym case wystarczyBETWEEN '2025-09-01' AND '2025-09-30'(daty są dzienne, więc zakres jest domknięty na obu końcach). - Anti-join (rekordy „bez powiązań”)
• Wzorzec:LEFT JOIN … WHERE prawa_strona.id IS NULLpokaże wiersze z lewej, które nie mają dopasowania (np. klienci bez zamówień). To praktyczny sposób na „brak danych” w relacji.. - Agregaty a NULL
•COUNT(kolumna)nie liczyNULL,COUNT(*)liczy wiersze.
•AVG,SUM,MAX,MINpomijająNULL(nie trzeba ich ręcznie filtrować).

