Ответ
Оператор GROUP BY группирует строки результирующего набора данных по одинаковым значениям в одном или нескольких указанных столбцах. Это позволяет применять агрегатные функции (COUNT, SUM, AVG, MAX, MIN) к каждой группе отдельно, а не ко всей таблице.
Базовый пример:
-- Подсчет количества сотрудников в каждом отделе
SELECT department_id, COUNT(*) AS employee_count
FROM employees
GROUP BY department_id;
| Результат: | department_id | employee_count |
|---|---|---|
| 10 | 5 | |
| 20 | 8 | |
| 30 | 3 |
Расширенный пример с несколькими полями и агрегацией:
-- Средняя зарплата и общий фонд оплаты по отделам и должностям
SELECT
department,
job_title,
AVG(salary) AS avg_salary,
SUM(salary) AS total_salary_budget
FROM employees
GROUP BY department, job_title;
Важные правила:
- В блоке
SELECTможно указывать только столбцы изGROUP BYили выражения с агрегатными функциями. - Для фильтрации групп (после агрегации) используется оператор
HAVING, а неWHERE.-- Найти отделы с более чем 5 сотрудниками SELECT department_id, COUNT(*) AS emp_count FROM employees GROUP BY department_id HAVING COUNT(*) > 5;
Ответ 18+ 🔞
А, ну ты глянь, какой прикол! Сидишь ты, значит, с этой своей базой данных, а там этих строк — овердохуища. И надо тебе их как-то по полочкам разложить, по смыслу. Вот тут-то и вылезает наш старый друг GROUP BY, блядь.
Этот оператор, сука, берёт все строки и сваливает их в кучки — по одинаковым значениям в указанных столбцах. Как детишек в детсаду по группам: кто в красной футболке — в одну кучку, кто в синей — в другую. А потом к каждой кучке можно применить агрегатные функции, типа посчитать, сложить или найти среднее. Не ко всей таблице сразу, а к каждой группе по отдельности, понимаешь? Хитро, блядь.
Смотри, как это просто выглядит:
-- Считаем, сколько народу сидит в каждом отделе, чтобы знать, где толпа, а где пусто
SELECT department_id, COUNT(*) AS employee_count
FROM employees
GROUP BY department_id;
| И вывалится тебе что-то типа: | department_id | employee_count |
|---|---|---|
| 10 | 5 | |
| 20 | 8 | |
| 30 | 3 |
Видишь? В отделе 20 — целых 8 человек, там, наверное, пиздец какой адок и куча совещаний. А в 30-м — всего трое, они, наверное, целый день в танчики играют.
А можно и посложнее, с разбивкой по двум полям:
-- Считаем среднюю зарплату и общий фонд оплаты, но не просто по отделам, а ещё и по должностям внутри них
SELECT
department,
job_title,
AVG(salary) AS avg_salary,
SUM(salary) AS total_salary_budget
FROM employees
GROUP BY department, job_title;
Тут уже каждая группа — это уникальная парочка «отдел + должность». Удобно, ёпта, смотреть, где менеджеры дохуя получают, а где кодеры — копейки.
А теперь, внимание, ебаный важный момент! Есть два железных правила, нарушишь — получишь ошибку и будешь сидеть, чесать репу:
- В блоке
SELECTты можешь тащить ТОЛЬКО те столбцы, по которым группируешь (вGROUP BY), или выражения с агрегатными функциями (COUNT,SUMи т.д.). Всё остальное — нахуй. SQL просто не поймёт, какую из многих строк в группе тебе показать. - Фильтровать уже сгруппированные результаты надо через
HAVING, а не черезWHERE.WHEREработает ДО группировки, отсеивает строки. АHAVING— ПОСЛЕ, отсеивает целые группы. Запутаешься — будет тебе чих-пых в сраку.
-- Найти отделы, где народу больше пяти, чтобы знать, где точно пиздец
SELECT department_id, COUNT(*) AS emp_count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 5; -- Вот тут HAVING, а не WHERE, запомни, блядь!
Вот и вся магия, сука. Сгруппировал, посчитал, отфильтровал — и уже не просто куча данных, а осмысленная статистика. Красота, блядь!