🎯 Cele lekcji

📊

1. Funkcje agregujące

FunkcjaOpisPrzykład
COUNT(*)Liczba wierszy (łącznie z NULL)COUNT(*) — wszystkie wiersze
COUNT(kolumna)Liczba wierszy z wartością (ignoruje NULL)COUNT(email) — wiersze z emailem
COUNT(DISTINCT kol)Liczba unikalnych wartościCOUNT(DISTINCT id_klienta)
SUM(kolumna)Suma wartości (ignoruje NULL)SUM(kwota)
AVG(kolumna)Średnia arytmetyczna (ignoruje NULL)AVG(cena)
MIN(kolumna)Wartość minimalnaMIN(cena)
MAX(kolumna)Wartość maksymalnaMAX(cena)
-- Podstawowe agregacje na tabeli zamówień
SELECT
  COUNT(*) AS liczba_zamowien,
  SUM(kwota) AS suma_sprzedazy,
  AVG(kwota) AS srednia_kwota,
  MIN(kwota) AS min_kwota,
  MAX(kwota) AS max_kwota
FROM zamowienia
WHERE YEAR(data) = 2024;

-- Zaokrąglanie wyników
SELECT ROUND(AVG(cena), 2) AS srednia_cena
FROM produkty;

-- COALESCE — zamień NULL na wartość domyślną
SELECT imie, COALESCE(miasto, 'Nieznane') AS lokalizacja
FROM klienci;
📦

2. GROUP BY — grupowanie wyników

-- Ile zamówień złożył każdy klient?
SELECT id_klienta,
       COUNT(*) AS liczba_zamowien,
       SUM(kwota) AS suma
FROM zamowienia
GROUP BY id_klienta
ORDER BY suma DESC;

-- Zamówienia per klient (z nazwiskiem przez JOIN)
SELECT k.imie, k.nazwisko,
       COUNT(z.id_zamowienia) AS liczba_zamowien,
       SUM(z.kwota) AS laczna_kwota
FROM klienci k
LEFT JOIN zamowienia z ON k.id_klienta = z.id_klienta
GROUP BY k.id_klienta, k.imie, k.nazwisko
ORDER BY laczna_kwota DESC;

-- Średnia cena per kategoria
SELECT kategoria,
       COUNT(*) AS ile_produktow,
       ROUND(AVG(cena), 2) AS srednia_cena,
       SUM(cena * ilosc) AS wartosc_magazynu
FROM produkty
GROUP BY kategoria;
Zasada GROUP BY: w SELECT możesz mieć tylko kolumny wymienione w GROUP BY oraz wyniki funkcji agregujących. Reguła "nie-agregowane kolumny muszą być w GROUP BY".
🔬

3. HAVING — filtrowanie grup

-- Kategorie z sumą sprzedaży > 1000 PLN
SELECT kategoria, SUM(cena * ilosc) AS wartosc
FROM produkty
GROUP BY kategoria
HAVING SUM(cena * ilosc) > 1000;

-- Klienci z więcej niż 3 zamówieniami
SELECT id_klienta, COUNT(*) AS ile
FROM zamowienia
GROUP BY id_klienta
HAVING COUNT(*) > 3;

-- WHERE filtruje PRZED grupowaniem, HAVING PO grupowaniu
SELECT kategoria, AVG(cena) AS srednia
FROM produkty
WHERE aktywny = 1          -- filtruje wiersze (przed grupowaniem)
GROUP BY kategoria
HAVING AVG(cena) > 200   -- filtruje grupy (po grupowaniu)
ORDER BY srednia DESC;
KlauzulaKiedy działaMoże używać funkcji agg.?
WHEREPrzed grupowaniem (na wierszach)NIE
HAVINGPo grupowaniu (na grupach)TAK
✏️

Zadania interaktywne

Zadanie 1Quiz: WHERE vs HAVING

Chcesz pokazać tylko kategorie, w których średnia cena produktów przekracza 500 PLN. Której klauzuli użyjesz?

  • WHERE AVG(cena) > 500
  • HAVING AVG(cena) > 500
  • GROUP BY AVG(cena) > 500
  • ORDER BY AVG(cena) > 500
Zadanie 2Dopasuj funkcję agregującą do zadania
Ile rekordów jest w tabeli?
Jaka jest całkowita wartość sprzedaży?
Jaka jest najniższa cena produktu?
Jaka jest średnia wartość zamówienia?
Zadanie 3Napisz zapytanie z GROUP BY i HAVING

Napisz zapytanie, które dla każdej kategorii podaje liczbę produktów i średnią cenę, ale tylko dla kategorii mających więcej niż 3 produkty:

📌 Zapamiętaj