Может задавать условие поиска для групп (как для отдельных строк SELECT)
HAVING поле GROUP BY
Здесь сравниваются атрибуты групп
Пример. Определить среднегодовой оклад в отделе, где насчитывается более двух сотрудников:
SELECT Должность, COUNT(*), AVG(Оклад)*12
FROM Сотрудники
GROUP BY Должность
HAVING COUNT(*)>2
В данном запросе могут присутствовать как WHERE так и HAVING. Сначала применяется WHERE. Из оставшихся строк формируется группа в соответствии с GROUP BY. К полученным группам применяется предложение HAVING.
Пример. Составить список отделов, в которых работают по крайней мере два инженера:
SELECT Отдел
FROM Сотрудники
WHERE Должность = 'Инженер'
GROUP BY Отдел
HAVING COUNT(*) > 2
Предложение HAVING может сравнивать различные атрибуты групп.
Пример. Составить список отделов, средняя премия в которых превышает 85% оклада:
Предложение HAVING может сравнивать атрибуты разных групп, для этого необходимо использовать подзапросы.
Пример. Получить список должностей, средний оклад которых больше среднего размера оклада заведующего:
SELECT Должность, AVG(Оклад)
FROM Сотрудники
GROUP BY Должность
HAVING AVG(Оклад) > (SELECT AVG(Оклад)
FROM Сотрудники
WHERE Должность = ‘Заведующий’)
Подзапрос – это дополнительный метод манипулирования с несколькими таблицами. Это оператор SELECT, вложенный:
в предложение WHERE, HAVING или SELECT другого оператора SELECT;
в оператор INSERT, UPDATE или DELETE
в другой подзапрос.
Именно возможность вложения операторов SQL друг в друга является причиной, по которой SQL первоначально был назван Structured Query Language. Термин подзапрос часто используется для ссылки на всю совокупность операторов, которая включает один или несколько подзапросов, а также на отдельное вложение. Каждый включающий оператор – следующий по старшинству уровень в подзапросе – представляет собой внешний уровень для внутреннего подзапроса.
Упрощенный синтаксис подзапроса.
Условия поиска, относящиеся к другому запросу, также могут встречаться в предложении WHERE внешнего запроса – до или после внутреннего запроса.
SELECT [DISTINCT]
<Список полей> или *
FROM <Список таблиц> Начало внешнего оператора SELECT
( SELECT [DISTINCT] список выбора подзапроса Подзапрос
FROM <Список таблиц> заключенный
WHERE условия ) в скобки.
[GROUP BY <Список полей для группирования>]
[HAVING <Условие группирования>]
[ORDER BY <Список полей для сортировки>]
Как работает подзапрос?
Подзапросы возвращают результаты внутреннего запроса во внешнее предложение и имеют две основные формы: некоррелированную и коррелированную. Первая реализуется (концептуально) “изнутри наружу”, т.е. внешний запрос выполняет то или иное действие, основываясь на результатах выполнения внутреннего запроса. Вторую форму подзапроса можно представить так: внешний оператор SQL предоставляет значения для внутреннего подзапроса, которые будут использоваться при его выполнении. Затем результаты выполнения подзапроса возвращаются на внешний запрос.
В коррелированном подзапросе внутренний запрос не может быть реализован немедленно: он ссылается на внешний запрос и выполняется поочередно для каждой строки во внешнем запросе.
Как коррелированные, так и некоррелированные запросы бывают трех типов, в зависимости от элементов в предложении WHERE внешнего запроса.
Подзапросы, которые не возвращают ни одного или возвращают несколько элементов (начинаются с IN или с оператора сравнения, содержат ключевые слова ANY или ALL).
Подзапросы, которые возвращают единственное значение (начинаются с простого оператора сравнения).
Подзапросы, которые представляют собой тест на осуществление (начинаются с EXISTS).
Пример. Найти всех сотрудников, у которых должность как у Реброва, а именно заведующий (некоррелированный подзапрос):