Verwendung von HAVING ohne GROUP BY in SQL-Abfragen

26

HAVINGMuss es für die Verwendung in SQL-Abfragen eine geben, GROUP BYum die Spaltennamen zu aggregieren?

Gibt es spezielle Fälle, in denen es möglich ist, HAVINGohne GROUP BYSQL-Abfragen zu verwenden?

Müssen sie gleichzeitig existieren?

Computerfreak
quelle

Antworten:

25

Nein.

Sie müssen nicht koexistieren, wie die Tatsache belegt, dass die folgende Abfrage in Oracle funktioniert:

select * from dual having 1 = 1;

In ähnlicher Weise funktioniert in PostgreSQL die folgende Abfrage:

select 1 having 1 = 1;

Also having nicht erforderlich group by .

Nachdem wird angewendet , nachdem die Aggregation Phase und muss verwendet werden , wenn Sie aggregierte Ergebnisse filtern möchten. Das Gegenteil ist also nicht der Fall, und Folgendes wird nicht funktionieren:

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

Sie müssen in diesem Fall wie folgt ersetzen wheredurch having:

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

Hinweis: Das folgende Abfrageformular funktioniert auch:

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

Sie können sehen, dass using havingeinfach eine Kurzversion dieser letzten Abfrage ist.


Zusammenfassend havingwird nach der group byPhase whereangewendet, wohingegen vor der group byPhase angewendet wird.

Colin 't Hart
quelle
2
Ein weiteres Beispiel:SELECT MIN(a) AS mina, MAX(a) As maxa FROM mytable HAVING MIN(a) < MAX(a);
ypercubeᵀᴹ
1
Ja. Und PostgreSQL erlaubt das folgende Konstrukt, select 1 having count(*) = 1;das ich noch nicht verstanden habe.
Colin 't Hart
SQL Server erlaubt auch, SELECT 1 AS id, 'Colin' AS name;während andere wie Oracle eine spezielle dualTabelle haben. Ich glaube nicht, dass eine dieser Syntaxen ANSI / ISO SQL ist (was erfordert FROM).
ypercubeᵀᴹ
Ich habe nicht das Fehlen gemeint, fromsondern den Verweis auf count(*)in der havingKlausel ohne Angabe darüber, über welche Spalten dies aggregiert wird. Vermutlich aggregiert es über alle Spalten in der selectKlausel.
Colin 't Hart
Ach ok Ja, ich bin damit einverstanden, dass es das ist, was es tut (aggregieren Sie über alle Zeilen, die Sie meinen - über alle Zeilen einer leeren Tabelle).
ypercubeᵀᴹ
4

Mit wird nach Gruppen gefiltert.

Mit der where-Klausel werden Zeilen gefiltert.

sqlengineer
quelle
1
Ihre erste Aussage ist nicht korrekt. havingwird angewendet , nachdem die Aggregationsphase so kann verwendet werden Filtergruppen.
Colin 't Hart
1

HAVING filtert die Gruppen. Wenn Sie keine GROUP BY-Ursache haben, wird in allen Zeilen eine Gruppe angezeigt. Wenn also das Prädikat in HAVING als wahr ausgewertet wird, erhalten Sie eine Zeile, andernfalls keine Zeilen.

msi77
quelle
1

In Abwesenheit der GROUP BY-Klausel betrachtet die Abfrage die gesamte Beziehung als eine Gruppe.

z.B

     select count(*)
     from dual
     having count(*) > 5;
Vikrant Singh
quelle