Ils n'ont pas à coexister, comme le prouve le fait que la requête suivante dans Oracle fonctionne:
select*from dual having1=1;
De même, dans PostgreSQL, la requête suivante fonctionne:
select1having1=1;
havingNe 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
groupby a
where c >1;
Vous devez remplacer wherepar havingdans ce cas, comme suit:
select a, count(*)as c
from mytable
groupby a
having c >1;
NB Le formulaire de requête suivant fonctionnera également:
select*from(select a, count(*)as c
from mytable
groupby 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.
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ᵀᴹ
4
Avoir est utilisé pour filtrer les groupes.
La clause where est utilisée pour filtrer les lignes.
Votre première déclaration n'est pas correcte. havingest appliqué après la phase d'agrégation et peut donc être utilisé pour filtrer les groupes.
Colin 't Hart
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.
SELECT MIN(a) AS mina, MAX(a) As maxa FROM mytable HAVING MIN(a) < MAX(a);
select 1 having count(*) = 1;
que je n'ai pas encore saisie.SELECT 1 AS id, 'Colin' AS name;
tandis que d'autres comme Oracle ont unedual
table spéciale . Je ne pense pas que l'une de ces syntaxes soit ANSI / ISO SQL (ce qui nécessiteFROM
).from
mais la référence àcount(*)
dans lahaving
clause sans aucune indication quant aux colonnes sur lesquelles cela est agrégé. Vraisemblablement, il agrège toutes les colonnes de laselect
clause.Avoir est utilisé pour filtrer les groupes.
La clause where est utilisée pour filtrer les lignes.
la source
having
est appliqué après la phase d'agrégation et peut donc être utilisé pour filtrer les groupes.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.
la source
En l'absence de clause GROUP BY, la requête considère la relation entière comme un seul groupe.
par exemple
la source