Коротка відповідь
juniorHAVING — це фільтр, що застосовується до результатів агрегованих груп після GROUP BY. Він дозволяє обмежити рядки, що задовольняють умовам агрегатних функцій, наприклад, `HAVING COUNT(*) > 5`. Таким чином, HAVING працює як WHERE, але для групованих даних.
Повне пояснення
Що це і навіщо
HAVING – оператор SQL, який використовується після GROUP BY для фільтрації результатів агрегатних функцій. Він дозволяє обмежити групи, що задовольняють певній умові, наприклад, кількість записів у групі або суму.
Ключові принципи
- Працює лише з результатами
GROUP BY. - Умова може містити агрегатні функції (
COUNT,SUM,AVGтощо). - Якщо потрібен фільтр до неагрегованих колонок, слід використовувати
WHERE.
Як це працює
- SQL‑парсер спочатку виконує
SELECTіGROUP BY, створюючи тимчасову таблицю з групами. - Потім застосовує
HAVING, відкидаючи ті групи, що не відповідають умові. - Нарешті повертає остаточний результат.
Практика й реалізація
SELECT department, COUNT(*) AS cnt
FROM employees
GROUP BY department
HAVING COUNT(*) > 10;
У цьому прикладі повертаються лише департаменти з більш ніж 10 працівниками.
Тестування
- У Jest можна перевірити, що запит повертає очікувану кількість рядків:
const result = await db.query(`SELECT department, COUNT(*) AS cnt FROM employees GROUP BY department HAVING COUNT(*) > 10`);
expect(result.rows).toHaveLength(expectedCount);
Оптимізація запитів
- Індекси на колонках, що використовуються в
GROUP BY, значно зменшують час агрегації. - Використання
EXPLAINдопомагає зрозуміти, чи планує виконувати індексний скан.
Безпека
- Умови в
HAVINGне підлягають SQL‑ін’єкції, якщо вони будуть параметризовані.
Особливості в контексті ORM
- У Prisma можна використати
groupByз полемhaving:prisma.employee.groupBy({ by: ['department'], having: { cnt: { gt: 10 } } }).
Часті помилки
- Використання
HAVINGзамістьWHEREдля фільтрації неагрегованих колонок. - Забудова
GROUP BY, що призводить до помилки «column must appear in GROUP BY clause». - Неправильне використання агрегатних функцій у
HAVING, що викликає помилку типу «invalid reference to column».
Cheatsheet
WHERE– фільтр до рядків.HAVING– фільтр після групування.- Умова в
HAVINGможе містити агрегатні функції, а уWHERE– ні.