HAVING-спецификация

Функция

Задает ограничение для сгруппированной таблицы, полученной путем применения предшествующей <FROM-спецификации>, <WHERE-спецификации> или <GROUP BY-спецификации>, которое состоит в том, что исключаются группы, не удовлетворяющие <логическому выражению>.

Спецификация

   
<HAVING-спецификация>::=

Синтаксические правила

  1. Каждый элемент <логического выражения> (<спецификация столбца>, <значимое выражение> или <SQL-параметр>) должен однозначно указывать на группируемый столбец из результата предшествующих <FROM-спецификации>, <WHERE-спецификации> или <GROUP BY-спецификации>.

  2. Каждая <спецификация столбца>, содержащаяся в <подзапросе> <логического выражения> и указывающая на внешний столбец, должна быть группирующим столбцом предшествующих <FROM-спецификации>, <WHERE-спецификации> или <GROUP BY-спецификации> либо аргументом агрегатной функции.

    select distinct make from auto
    group by make
    having max(year) > (select min(auto.year) from auto, person
    where person.personid=auto.personid and  length(auto.make)=length(person.name));
  3. Запрещено обращение из подзапроса в <HAVING-спецификации> к негруппируемым столбцам.

  4. Числовые значения <значимого выражения>, заданного в <логическом выражении>, допускается представлять в строковом виде.

    select name, count(*) from person
    group by name having max(salary) > '50000';

Общие правила

  1. Если предшествующая спецификация не содержит <GROUP BY-спецификацию>, то результатом <HAVING-спецификации> является единственная группа, а группируемый столбец отсутствует.

  2. <Логическое выражение> применяется к каждой группе из результата предшествующих спецификаций. Результатом <HAVING-спецификации> будет сгруппированная таблица, в которую войдут те группы, для которых результатом <логического выражения> будет значение «истина».

  3. Когда <логическое выражение> наложено на группу, то эта группа является аргументом любой агрегатной функции, непосредственно содержащейся в <логическом выражении>, если только <спецификация столбца> в агрегатной функции не является внешней ссылкой.

  4. Все <подзапросы> в <логическом выражении> выполняются для каждой группы, а полученные результаты применяются к каждой группе, удовлетворяющей <логическому выражению>. Если <подзапрос> содержит внешнюю ссылку на столбец, то она является ссылкой на значение этого столбца в данной группе.

    select make from auto
    group by make
    having max(year+1900)
    <(select to_number(to_char(sysdate, 'yyyy')));
  5. В <HAVING-спецификации> можно указывать только те столбцы и значимые выражения, по которым делается группировка.

    Получить список производителей машин черного, белого и зеленого цвета с числом цилиндров больше 6:

    select make, cylnders, color from auto
    where color in ('BLACK','WHITE','GREEN')
    group by make, cylnders, color
    having max(cylnders)>6;
  6. Если в <HAVING-спецификации> используется <SQL-параметр>, то его тип данных должен быть указан обязательно.

    select distinct model, :year (int)+1900  from auto
    group by model, year+1900
    having :year (int)+1900 >1970 limit 3;
    71
    |124 SPORT COUPE     |       1971|
    |1275 GT             |       1971|
    |1302 S              |       1971|

  7. В SELECT-операторе можно указывать также целиком <значимое выражение>, по которому создается группировка или другие столбцы, используемые как аргументы агрегатных функций.

    select make, year+1900 from auto
    group by make, year+1900
    having max( year+1900) between 1969 and 1972;
  8. Если запрос с <HAVING-спецификацией> не содержит опции GROUP BY, то столбцы в SELECT и в HAVING конструкциях могут использоваться только как аргументы агрегатных функций.

    Допустимый запрос:

    select avg(salary) from tab_aggr having max(salary) > 20000;

    Недопустимые запросы:

    select salary from tab_aggr having max(salary) > 20000;
    select avg(salary) from tab_aggr having salary > 20000;
  9. В <HAVING-спецификации> разрешено использовать группированные CAST- и CASE-выражения.

    select make, cast(year+1900 as double)  from auto
    group by make, cast(year+1900 as double)
    having cast(year+1900 as double) >1970.05;