Використання 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;

Примітка. Наступна форма запиту також буде працювати:

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

Використовується для фільтрації груп.

де пункт використовується для фільтрування рядків.



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

1

HAVING фільтрує групи. Якщо у вас немає групової причини, усі рядки представляють одну групу. Отже, якщо предикат у HAVING оцінює як істинний, ви отримуєте один рядок, інакше немає рядків.


1

За відсутності пункту GROUP BY запит розглядає все відношення як одну групу.

напр

     select count(*)
     from dual
     having count(*) > 5;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.