HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>Иногда встречаются задачи, в которых требуется отфильтровать записи после группировки.</p>
1 <p>Иногда встречаются задачи, в которых требуется отфильтровать записи после группировки.</p>
2 <p>Для примера представим, что нам нужно вывести суммарное время, проведенное на платформе каждым пользователем:</p>
2 <p>Для примера представим, что нам нужно вывести суммарное время, проведенное на платформе каждым пользователем:</p>
3 <p><a>View on DB Fiddle</a></p>
3 <p><a>View on DB Fiddle</a></p>
4 <p>Мы видим, что кто-то из пользователей провел много времени, а кто-то - совсем мало. Мы можем выбрать пользователей, которые провели на платформе меньше 30 минут, а затем связаться с ними и узнать, что именно им не понравилось.</p>
4 <p>Мы видим, что кто-то из пользователей провел много времени, а кто-то - совсем мало. Мы можем выбрать пользователей, которые провели на платформе меньше 30 минут, а затем связаться с ними и узнать, что именно им не понравилось.</p>
5 <p>Подобные условия невозможно задать с помощью WHERE, потому что они применяются к выборке до момента группировки. У нас немного другой случай - мы хотим задать условие на результат агрегатной функции после проведения группировки.</p>
5 <p>Подобные условия невозможно задать с помощью WHERE, потому что они применяются к выборке до момента группировки. У нас немного другой случай - мы хотим задать условие на результат агрегатной функции после проведения группировки.</p>
6 <p>В этой задаче понадобится дополнение к GROUP BY, которое называется HAVING. Именно его мы изучим в этом уроке.</p>
6 <p>В этой задаче понадобится дополнение к GROUP BY, которое называется HAVING. Именно его мы изучим в этом уроке.</p>
7 <h2>Ключевое слово HAVING</h2>
7 <h2>Ключевое слово HAVING</h2>
8 <p>С помощью ключевого слова HAVING мы можем задать условия на строки выборки после группировки данных.</p>
8 <p>С помощью ключевого слова HAVING мы можем задать условия на строки выборки после группировки данных.</p>
9 <p>Попробуем найти пользователей, которые потратили менее 30 минут в онлайн-школе. Для этого напишем такой запрос:</p>
9 <p>Попробуем найти пользователей, которые потратили менее 30 минут в онлайн-школе. Для этого напишем такой запрос:</p>
10 <p><a>View on DB Fiddle</a></p>
10 <p><a>View on DB Fiddle</a></p>
11 <p>Таких пользователей оказалось 6 человек.</p>
11 <p>Таких пользователей оказалось 6 человек.</p>
12 <h2>Чем HAVING отличается от WHERE</h2>
12 <h2>Чем HAVING отличается от WHERE</h2>
13 <p>Давайте дополним наш запрос - укажем, что искать пользователей мы будем только среди первых 40 человек. Для этого добавим условие user_id &lt;= 40:</p>
13 <p>Давайте дополним наш запрос - укажем, что искать пользователей мы будем только среди первых 40 человек. Для этого добавим условие user_id &lt;= 40:</p>
14 <p><a>View on DB Fiddle</a></p>
14 <p><a>View on DB Fiddle</a></p>
15 <p>Обратим внимание на синтаксис запроса. Условия в HAVING проверяются после группировки, поэтому они задаются после предложения GROUP BY. В этом и состоит отличие от условий WHERE, которые применяются к строкам исходной таблицы до группировки.</p>
15 <p>Обратим внимание на синтаксис запроса. Условия в HAVING проверяются после группировки, поэтому они задаются после предложения GROUP BY. В этом и состоит отличие от условий WHERE, которые применяются к строкам исходной таблицы до группировки.</p>
16 <p>Таким образом, сначала мы убрали из исходной таблицы всех пользователей с user_id &gt; 40, затем провели группировку и посчитали суммарное время, а после этого отсеяли тех, кто пользовался платформой дольше 30 минут.</p>
16 <p>Таким образом, сначала мы убрали из исходной таблицы всех пользователей с user_id &gt; 40, затем провели группировку и посчитали суммарное время, а после этого отсеяли тех, кто пользовался платформой дольше 30 минут.</p>
17 <p>В этой ситуации мы могли бы добавить условие на user_id и в HAVING и получили бы тот же результат:</p>
17 <p>В этой ситуации мы могли бы добавить условие на user_id и в HAVING и получили бы тот же результат:</p>
18 <p><a>View on DB Fiddle</a></p>
18 <p><a>View on DB Fiddle</a></p>
19 <p>Такой запрос будет выполняться дольше, особенно если таблицы будут большими. Лучше сперва исключить ненужных пользователей, сгруппировать уже отфильтрованные данные и затем посчитать агрегатные функции.</p>
19 <p>Такой запрос будет выполняться дольше, особенно если таблицы будут большими. Лучше сперва исключить ненужных пользователей, сгруппировать уже отфильтрованные данные и затем посчитать агрегатные функции.</p>
20 <h2>Выводы</h2>
20 <h2>Выводы</h2>
21 <p>В этом уроке мы научились задавать условия на значение полей после группировки и применения агрегатных функций. Теперь вы знаете, как отфильтровать строки в сгруппированных данных с помощью HAVING.</p>
21 <p>В этом уроке мы научились задавать условия на значение полей после группировки и применения агрегатных функций. Теперь вы знаете, как отфильтровать строки в сгруппированных данных с помощью HAVING.</p>
22 <p>Еще мы разобрали разницу между WHERE и HAVING:</p>
22 <p>Еще мы разобрали разницу между WHERE и HAVING:</p>
23 <ul><li>Если мы задаем условия через WHERE, они применяются к строкам исходной таблицы до группировки данных. Поэтому WHERE записывается до GROUP BY</li>
23 <ul><li>Если мы задаем условия через WHERE, они применяются к строкам исходной таблицы до группировки данных. Поэтому WHERE записывается до GROUP BY</li>
24 <li>Если мы задаем условия через HAVING, они проверяются уже после группировки данных и записываются после предложения GROUP BY</li>
24 <li>Если мы задаем условия через HAVING, они проверяются уже после группировки данных и записываются после предложения GROUP BY</li>
25 </ul>
25 </ul>