Использование HAVING без GROUP BY в SQL-запросах


26

Чтобы использовать HAVINGв запросах SQL, должен ли быть GROUP BYагрегировать имена столбцов?

Существуют ли особые случаи, когда можно использовать HAVINGбез GROUP BYSQL-запросов?

Должны ли они сосуществовать одновременно?

Ответы:


25

Нет.

Они не должны сосуществовать, что подтверждается тем фактом, что следующий запрос в Oracle работает:

select * from dual having 1 = 1;

Аналогично, в PostgreSQL работает следующий запрос:

select 1 having 1 = 1;

Так having не требует group by .

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

select a, count(*) as c
from mytable
group by a
where c > 1;

Вам нужно заменить whereс havingв этом случае выглядит следующим образом :

select a, count(*) as c
from mytable
group by a
having c > 1;

NB Следующая форма запроса также будет работать:

select *
from (
  select a, count(*) as c
  from mytable
  group by a
)
where c > 1;

Вы можете видеть, что использование having- это просто сокращенная версия этого последнего запроса.


Таким образом, havingприменяются послеgroup by того, как фазы , тогда как whereприменяются перед тем в group byфазе.


2
Другой пример:SELECT MIN(a) AS mina, MAX(a) As maxa FROM mytable HAVING MIN(a) < MAX(a);
ypercubeᵀᴹ

1
Да. И PostgreSQL позволяет следующую конструкцию, select 1 having count(*) = 1;которую я еще не понял.
Colin 't Hart

SQL Server тоже позволяет, в SELECT 1 AS id, 'Colin' AS name;то время как другие, как Oracle, имеют специальную dualтаблицу. Я не думаю, что какой-либо из этих синтаксисов является ANSI / ISO SQL (который требует FROM).
ypercubeᵀᴹ

Я имел в виду не отсутствие, fromа ссылку count(*)в havingпредложении без указания того, по каким столбцам это агрегируется. Предположительно, он объединяет все столбцы в selectпредложении.
Colin 't Hart

Ах хорошо. Да, я согласен, что это то, что он делает (агрегирует по всем строкам, которые вы имеете в виду - по всем строкам пустой таблицы).
ypercubeᵀᴹ

4

Наличие используется для фильтрации групп.

предложение where используется для фильтрации строк.



1
Ваше первое утверждение не правильно. havingбудет применяться после того, как фаза агрегации , так может быть использована для фильтров групп.
Colin 't Hart

1

HAVING фильтрует группы. Если у вас нет причины GROUP BY, все строки представляют одну группу. Таким образом, если предикат в HAVING оценивается как true, вы получите одну строку, иначе строк нет.


1

При отсутствии предложения GROUP BY запрос рассматривает все отношение как одну группу.

например

     select count(*)
     from dual
     having count(*) > 5;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.