Lekcje modułu (3/4)
Grupowanie z GROUP BY
W module 2 nauczyłeś się, że COUNT(*), AVG(...), SUM(...) redukują wszystko
wierszy do pojedynczego wiersza wyniku. Ale co, jeśli chcesz przeciętnej pensji
dla każdego działu, a nie dla całej firmy? Chcesz jeden wiersz per
grupa. To jest zadanie GROUP BY.
Składnia
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM table
GROUP BY grouping_column;Przeczytaj po angielsku: ”podziel wiersze na grupy o tej samej wartości
grouping_column i dla każdej grupy oblicz agregat".
-- Average salary per department:
SELECT department_id, AVG(salary) AS average
FROM employees
GROUP BY department_id;Wynik zawiera jeden wiersz dla każdego odrębnego department_id znalezionego w
KODEF1. Otrzymasz 5 wierszy: po jednym dla każdego z 4 działów (1, 2,
3, 4) plus jeden dla NULL (Andrea Costa).
Z JOIN dla czytelnych nazw
Często chcesz grupować według department_id, ale pokaż nazwę pliku
dział. Łączysz GROUP BY z JOIN:
SELECT d.name AS department,
COUNT(*) AS count,
AVG(e.salary) AS average_salary
FROM employees AS e
JOIN departments AS d ON e.department_id = d.id
GROUP BY d.name
ORDER BY count DESC;Jest to pełnoprawne zapytanie business intelligence: w trzech linijkach informuje, ilu pracowników ma każdy dział i ile na nich zarabia średnia, posortowana od największej do najmniejszej.
Złota zasada
Kiedy używasz GROUP BY, każda kolumna w SELECT musi być:
- jedna z kolumn grupujących (np.
department_id,d.name), lub - wewnątrz funkcji agregującej (np.
AVG(salary),COUNT(*)).
-- ERROR: first_name is neither in GROUP BY nor inside an aggregate
SELECT department_id, first_name, AVG(salary)
FROM employees
GROUP BY department_id;PostgreSQL zwraca jawny błąd (kolumna " musi pojawić się w kolumnie GROUP BY
klauzuli lub być użyte w funkcji agregującej”). To częste zjawisko w pierwszych tygodniach
błąd: jeśli to zobaczysz, zatrzymaj się i zadaj sobie pytanie: „jaka jest wartość”.
first_name dla grupy 3 osób?”_ — nie ma jednej odpowiedzi, oraz
dlatego silnik odmawia.
Spróbuj
Dla każdego działu oblicz, ilu zatrudnia pracowników. Zwróć dwie kolumny: nazwę działu (departments.name) i liczbę pracowników. Jeden wiersz na każdy dział.
Pokaż wskazówkę
Agreguj za pomocą COUNT(*) i grupuj według d.name. SELECT musi zawierać tylko kolumnę grupującą i agregat.
Rozwiązanie dostępne po 3 próbach
Przejrzyj ćwiczenie
Dla każdego działu (departments.name) oblicz średnie wynagrodzenie (AVG(salary)) jego pracowników, posortowane od najwyższej do najniższej.
Pokaż wskazówkę
AVG(e.salary) jako suma, GROUP BY d.name, ORDER BY średnia DESC.
Rozwiązanie dostępne po 3 próbach