HAVING
HAVING фильтрует группы после GROUP BY. Он нужен, когда условие зависит от агрегата, например «только группы, где больше 1000 строк». Работаем с tutorial.aapl_historical_stock_price и tutorial.crunchbase_companies.
Почему не WHERE
Заголовок раздела «Почему не WHERE»WHERE работает до группировки, когда агрегатов ещё нет. Условие с агрегатной функцией в WHERE вызовет ошибку.
-- ошибка: агрегат нельзя использовать в WHERESELECT year, month, MAX(high) AS month_highFROM tutorial.aapl_historical_stock_priceWHERE MAX(high) > 400GROUP BY year, month;HAVING стоит после GROUP BY. Он видит уже посчитанные агрегаты:
SELECT year, month, MAX(high) AS month_highFROM tutorial.aapl_historical_stock_priceGROUP BY year, monthHAVING MAX(high) > 400ORDER BY year, month;Запрос вернёт 35 месяцев, где цена хотя бы раз поднималась выше 400.
| WHERE | HAVING | |
|---|---|---|
| Когда работает | До GROUP BY | После GROUP BY |
| Что фильтрует | Строки | Группы |
| Агрегаты в условии | Нельзя | Можно |
Порядок частей запроса
Заголовок раздела «Порядок частей запроса»SELECTFROMWHEREGROUP BYHAVINGORDER BY
Пишите части запроса именно в таком порядке.
WHERE и HAVING вместе
Заголовок раздела «WHERE и HAVING вместе»WHERE убирает ненужные строки заранее. HAVING отбирает группы. Так запрос работает быстрее.
SELECT category_code, COUNT(*) AS companiesFROM tutorial.crunchbase_companiesWHERE country_code = 'USA'GROUP BY category_codeHAVING COUNT(*) >= 500ORDER BY companies DESC;Практика
Заголовок раздела «Практика»Решайте сами, без AI. Сначала напишите запрос, потом сверьтесь с проверкой, и только потом открывайте решение.
Задание 1
Заголовок раздела «Задание 1»Найдите годы, когда средний дневной объём торгов (volume) акций Apple был больше 35 миллионов. Покажите год и среднее значение.
Проверка: 2 строки: 2007 и 2008.
Решение
SELECT year, AVG(volume) AS avg_volumeFROM tutorial.aapl_historical_stock_priceGROUP BY yearHAVING AVG(volume) > 35000000ORDER BY year;Задание 2
Заголовок раздела «Задание 2»Покажите категории (category_code) компаний из tutorial.crunchbase_companies, в которых не меньше 1000 компаний. Не включайте компании без категории. Отсортируйте от большей категории к меньшей.
Проверка: 16 строк. Первая: biotechnology, 4468.
Решение
SELECT category_code, COUNT(*) AS companiesFROM tutorial.crunchbase_companiesWHERE category_code IS NOT NULLGROUP BY category_codeHAVING COUNT(*) >= 1000ORDER BY companies DESC;Задание 3
Заголовок раздела «Задание 3»Посчитайте суммарный объём торгов по месяцам 2014 года. Оставьте месяцы, где сумма больше 500 миллионов акций.
Проверка: 7 строк, с июня по декабрь. Для июня: 853087800.
Решение
SELECT year, month, SUM(volume) AS volume_sumFROM tutorial.aapl_historical_stock_priceWHERE year = 2014GROUP BY year, monthHAVING SUM(volume) > 500000000ORDER BY month;