Язык запросов SQL

Подзапросы в предложении HAVING



Подзапросы в предложении HAVING

Коррелированный подзапрос можно задавать не только в предложении WHERE, но и в предложении HAVING. Как уже говорилось в главе 9, перед этим предложением обычно находится предложение GROUP BY. Предложение HAVING действует как фильтр, который должен ограничивать группы, созданные предложением GROUP BY. Группы, которые не удовлетворяют условию предложения HAVING, в результат не попадут. Если предложение HAVING используется таким образом, то оно проверяется для каждой группы, созданной
предложением GROUP BY. Если же предложения GROUP BY нет, то предложение HAVING проверяется для всего набора строк, переданного предложением WHERE. Тогда этот набор считается одной группой. А если нет ни предложения WHERE, ни предложения GROUP BY, то условие предложения HAVING проверяется уже для всей таблицы:

SELECT TM1.EMPID

FROM TRANSMASTER TM1

         GROUP BY TM1.EMPID

         HAVING MAX (TM1.NET_AMOUNT) >= ALL

               (SELECT 2 * AVG (TM2.NET_AMOUNT)

                  FROM TRANSMASTER TM2

                  WHERE TM1.EMPID <> TM2.EMPID) ;

В этом запросе для одной и той же таблицы используются два псевдонима. В результате можно получить идентификаторы всех тех продавцов, у кого размер максимальной сделки как минимум в два раза превысил средний размер сделок остальных продавцов. Запрос работает следующим образом.

  1. Строки таблицы TRANSMASTER группируются внешним запросом по значениям столбца EMPID. Это делается с помощью предложений SELECT, FROM и GROUP BY.
  2. Получившиеся группы фильтруются предложением HAVING. В нем для каждой из групп вычисляется (с помощью функции МАХ) максимум значений из столбца NET_AMOUNT, которые находятся в строках этой группы.
  3. Внутренний запрос дважды проверяет среднее значение NET_AMOUNT для всех тех строк, в которых значения столбца EMPID отличаются от значения этого столбца в текущей группе внешнего запроса. Обратите внимание, что в последней строке запроса приходится указывать два значения, взятые из разных EMPID. Поэтому в предложениях FROM из внешнего и внутреннего запросов приходится для таблицы TRANSMASTER указывать два разных псевдонима.
  4. Эти псевдонимы затем используются в сравнении, расположенном в последней строке запроса. Цель их использования состоит в том, чтобы показать — обращение должно идти к значению столбца ЕМРЮ из текущей строки внутреннего подзапроса (ТМ2.ЕМРШ), а также к значению того же столбца, но на этот раз из текущей группы внешнего подзапроса (TM1.EMPID).


Содержание раздела