Uso di HAVING senza GROUP BY nelle query SQL


26

Per poter utilizzare HAVINGnelle query SQL, è necessario un a GROUP BYper aggregare i nomi delle colonne?

Ci sono casi speciali in cui è possibile utilizzare HAVINGsenza GROUP BYquery in SQL?

Devono coesistere contemporaneamente?

Risposte:


25

No.

Non devono coesistere, come dimostrato dal fatto che la seguente query in Oracle funziona:

select * from dual having 1 = 1;

Allo stesso modo, in PostgreSQL funziona la seguente query:

select 1 having 1 = 1;

Quindi having non richiede group by .

L'avere viene applicato dopo la fase di aggregazione e deve essere utilizzato se si desidera filtrare i risultati aggregati. Quindi il contrario non è vero e quanto segue non funzionerà:

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

In questo caso è necessario sostituire wherecon having, come segue:

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

NB Il seguente modulo di query funzionerà anche:

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

Si può vedere che l'utilizzo havingè semplicemente una versione abbreviata di quest'ultima query.


In sintesi, havingviene applicato dopo la group byfase mentre whereviene applicato prima della group byfase.


2
Un altro esempio:SELECT MIN(a) AS mina, MAX(a) As maxa FROM mytable HAVING MIN(a) < MAX(a);
ypercubeᵀᴹ

1
Sì. E PostgreSQL consente il seguente costrutto select 1 having count(*) = 1;che devo ancora comprendere.
Colin 't Hart,

Anche SQL Server lo consente, SELECT 1 AS id, 'Colin' AS name;mentre altri come Oracle hanno una dualtabella speciale . Non penso che nessuna di queste sintassi sia ANSI / ISO SQL (che richiede FROM).
ypercubeᵀᴹ

Non intendevo la mancanza di fromma il riferimento a count(*)nella havingclausola senza alcuna indicazione su quali colonne questo viene aggregato. Presumibilmente si aggrega su tutte le colonne della selectclausola.
Colin 't Hart,

Ah ok. Sì, sono d'accordo che è quello che fa (aggregare su tutte le righe che intendi - su tutte le righe di una tabella vuota).
ypercubeᵀᴹ


1

HAVING sta filtrando i gruppi. Se non si dispone della causa GROUP BY, tutte le righe presentano un gruppo. Quindi, se il predicato in HAVING viene valutato come vero, otterrai una riga, altrimenti nessuna riga.


1

In assenza della clausola GROUP BY, la query considera l'intera relazione come un gruppo.

per esempio

     select count(*)
     from dual
     having count(*) > 5;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.