Zastosowanie HAVING bez GROUP BY w zapytaniach SQL

26

Czy w celu użycia HAVINGw zapytaniach SQL musi istnieć GROUP BYagregacja nazw kolumn?

Czy są jakieś specjalne przypadki, w których można używać HAVINGbez GROUP BYzapytań SQL?

Czy muszą one współistnieć w tym samym czasie?

Computernerd
źródło

Odpowiedzi:

25

Nie.

Nie muszą one współistnieć, o czym świadczy fakt, że działa następujące zapytanie w Oracle:

select * from dual having 1 = 1;

Podobnie w PostgreSQL działa następujące zapytanie:

select 1 having 1 = 1;

Więc having nie wymaga group by .

Opcja jest stosowana po fazie agregacji i należy jej użyć, jeśli chcesz filtrować wyniki agregacji. Więc odwrotna sytuacja nie jest prawdą, a następujące działania nie będą działać:

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

Trzeba wymienić whereze havingw tym przypadku, jak następuje:

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

Uwaga: będzie również działał następujący formularz zapytania:

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

Widać, że użycie havingjest po prostu skróconą wersją tego ostatniego zapytania.


Podsumowując, havingjest stosowana pogroup by faza natomiast wherejest stosowany przed tym group byetapie.

Colin 't Hart
źródło
2
Kolejny przykład:SELECT MIN(a) AS mina, MAX(a) As maxa FROM mytable HAVING MIN(a) < MAX(a);
ypercubeᵀᴹ
1
Tak. A PostgreSQL pozwala na następującą konstrukcję, select 1 having count(*) = 1;którą muszę jeszcze zrozumieć.
Colin 't Hart
SQL Server też na to pozwala, SELECT 1 AS id, 'Colin' AS name;podczas gdy inni, tacy jak Oracle, mają specjalną dualtabelę. Nie sądzę, aby któraś z tych składni była ANSI / ISO SQL (która wymaga FROM).
ypercubeᵀᴹ
Nie miałem na myśli brak fromJednak odniesienie do count(*)w havingklauzuli bez wskazania co do tego, na które kolumny jest sumowane. Przypuszczalnie agreguje się we wszystkich kolumnach w selectklauzuli.
Colin 't Hart
Ach ok. Tak, zgadzam się, że tak właśnie działa (sumowanie we wszystkich wierszach, które masz na myśli - we wszystkich wierszach pustej tabeli).
ypercubeᵀᴹ
4

Posłuży do filtrowania grup.

gdzie klauzula służy do filtrowania wierszy.

sqlengineer
źródło
1
Twoje pierwsze stwierdzenie jest nieprawidłowe. havingjest stosowany po fazie agregacji, więc można go użyć do filtrowania grup.
Colin 't Hart
1

POSIADA filtrowanie grup. Jeśli nie masz przyczyny GROUP BY, wszystkie wiersze przedstawiają jedną grupę. Tak więc, jeśli predykat w HAVING ma wartość true, otrzymasz jeden wiersz, w przeciwnym razie nie będzie żadnych wierszy.

msi77
źródło
1

W przypadku braku klauzuli GROUP BY zapytanie traktuje całą relację jako jedną grupę.

na przykład

     select count(*)
     from dual
     having count(*) > 5;
Vikrant Singh
źródło