Utilisation de HAVING sans GROUP BY dans les requêtes SQL


26

Pour utiliser HAVINGdans les requêtes SQL, doit-il y avoir un GROUP BYpour regrouper les noms de colonne?

Existe-t-il des cas particuliers où il est possible d'utiliser HAVINGsans GROUP BYdans les requêtes SQL?

Doivent-ils coexister en même temps?

Réponses:


25

Non.

Ils n'ont pas à coexister, comme le prouve le fait que la requête suivante dans Oracle fonctionne:

select * from dual having 1 = 1;

De même, dans PostgreSQL, la requête suivante fonctionne:

select 1 having 1 = 1;

having Ne nécessite donc pasgroup by .

Avoir est appliqué après la phase d'agrégation et doit être utilisé si vous souhaitez filtrer les résultats d'agrégation. Donc, l'inverse n'est pas vrai, et ce qui suit ne fonctionnera pas:

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

Vous devez remplacer wherepar havingdans ce cas, comme suit:

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

NB Le formulaire de requête suivant fonctionnera également:

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

Vous pouvez voir que l'utilisation havingest simplement une version abrégée de cette dernière requête.


En résumé, havingest appliqué après la group byphase alors qu'il whereest appliqué avant la group byphase.


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

1
Oui. Et PostgreSQL permet la construction suivante select 1 having count(*) = 1;que je n'ai pas encore saisie.
Colin 't Hart

SQL Server le permet aussi, SELECT 1 AS id, 'Colin' AS name;tandis que d'autres comme Oracle ont une dualtable spéciale . Je ne pense pas que l'une de ces syntaxes soit ANSI / ISO SQL (ce qui nécessite FROM).
ypercubeᵀᴹ

Je ne voulais pas dire le manque de frommais la référence à count(*)dans la havingclause sans aucune indication quant aux colonnes sur lesquelles cela est agrégé. Vraisemblablement, il agrège toutes les colonnes de la selectclause.
Colin 't Hart

Ah ok. Oui, je suis d'accord que c'est ce qu'il fait (agréger sur toutes les lignes que vous voulez dire - sur toutes les lignes d'une table vide).
ypercubeᵀᴹ


1

AVOIR filtre les groupes. Si vous n'avez pas de cause GROUP BY, toutes les lignes présentent un groupe. Donc, si le prédicat dans HAVING est évalué comme vrai, vous obtenez une ligne, sinon aucune ligne.


1

En l'absence de clause GROUP BY, la requête considère la relation entière comme un seul groupe.

par exemple

     select count(*)
     from dual
     having count(*) > 5;
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.