После авторизации Вы получите доступ к файлам, скрытым материалам сайта, исходным кодам
возможность комментировать и т.д.

Вы можете авторизоваться на сайте всего одним кликом:

2016-07-08
SQL → Ограничение результатов с помощью оператора HAVING
Ограничение результатов

А что если вам понадобится получить список только тех авторов, у которых нет материалов? Рассмотрим запрос, который многие разработчики использовали бы в первую очередь.

Ограничение результатов с помощью оператора HAVING

SELECT author.name, COUNT(material.id) AS nummaterial
FROM author LEFT JOIN material
   ON authorid = author.id
WHERE nummaterial = 0
GROUP BY author.id

Выполнение данного кода приведет к тому, что phpMyAdmin выдаст ошибку:
#1054 - Unknown column 'nummaterial' in 'where clause'.

Причина, по которой выражение WHERE nummaterial = 0 приводит к ошибке, связана с тем, как MySQL-сервер обрабатывает результирующий набор. Сначала он формирует черновой комбинированный список авторов и материалов, взятых из таблиц author и material соответственно. Затем переходит к ключевому слову ON, которое следует за оператором FROM, и отбирает только релевантные строки (в нашем случае, это строки, которые связывают автора и количество материалов, где столбец nummaterial имеет значение 0). В завершение MySQL обращается к оператору GROUP BY: группи­ рует результаты по столбцу authorid, подсчитывает в каждой группе с помощью функции COUNT количество записей, которые не содержат NULL в столбце material.id, и выводит содержимое nummaterial.

Обратите внимание, что столбец nummaterial создан уже после того, как отработал оператор GROUP BY, который, в свою очередь, запускался после оператора WHERE. Следовательно, сообщение об ошибке возникло из-за того, что оператор WHERE искал столбец nummaterial, который еще не создан.

Если вы не хотите учитывать материалы, которые содержат слово «цыпленок», вы можете спокойно использовать оператор WHERE, поскольку это исключение не за­ висит от результатов выполнения оператора GROUP BY. Однако условия, которые затрагивают результат уже после группирования, должны перечисляться в рамках специального выражения HAVING. Ниже представлен исправленный запрос и его результат:

SELECT author.name, COUNT(material.id) AS nummaterial
FROM author LEFT JOIN material
   ON authorid = author.id
GROUP BY author.id
HAVING nummaterial = 0

Некоторые условия срабатывают внутри обоих операторов, как HAVING, так и WHERE. Например, чтобы исключить из списка результаты по имени конкретного автора, условие author.name != 'Имя Автора ' можно записать в любом из них. Результат останется неизменным вне зависимости от того, где произойдет ис­ ключение — до группирования результатов или после него. В таких случаях всегда лучше использовать оператор WHERE, поскольку он лучше оптимизируется внутри MySQL и поэтому работает быстрее.

430
0
Пожалуйста, авторизируйтесь, чтобы скачать архив с файлами урока