Je dois googler dans le mauvais sens ou je vais avoir un moment stupide dans le temps.
Quelle est la différence entre HAVING
et WHERE
dans une instruction SQL SELECT
?
EDIT: J'ai marqué la réponse de Steven comme étant la bonne, car elle contenait le bit d'information clé sur le lien:
Lorsque
GROUP BY
n'est pas utilisé,HAVING
se comporte comme une clauseWHERE
.
La situation dans laquelle j'avais vu le WHERE
n'avait pas GROUP BY
et c'est là que ma confusion a commencé. Bien sûr, jusqu'à ce que vous sachiez cela, vous ne pouvez pas le préciser dans la question.
Merci beaucoup pour toutes les réponses qui ont été très éclairantes.
HAVING spécifie une condition de recherche pour un groupe ou une fonction d'agrégat utilisée dans l'instruction SELECT.
HAVING: est utilisé pour vérifier les conditions after l’agrégation a lieu.
WHERE: est utilisé pour vérifier les conditions avant l’agrégation a lieu.
Ce code:
select City, CNT=Count(1)
From Address
Where State = 'MA'
Group By City
Vous donne un tableau de toutes les villes de MA et le nombre d'adresses dans chaque ville.
Ce code:
select City, CNT=Count(1)
From Address
Where State = 'MA'
Group By City
Having Count(1)>5
Vous donne un tableau des villes de MA avec plus de 5 adresses et le nombre d'adresses dans chaque ville.
La différence numéro un pour moi: si HAVING
était supprimé du langage SQL, la vie continuerait plus ou moins comme avant. Certes, les requêtes d'une minorité devraient être réécrites à l'aide d'une table dérivée, d'un CTE, etc., mais elles seraient sans doute plus faciles à comprendre et à gérer. Peut-être faudrait-il réécrire le code de l'optimiseur des fournisseurs pour tenir compte de cela, ce qui constituerait une opportunité d'amélioration dans le secteur.
Pensez maintenant à retirer WHERE
de la langue. Cette fois, la majorité des requêtes existantes devra être réécrite sans construction alternative évidente. Les codeurs devraient faire preuve de créativité, par exemple jointure interne à une table connue pour contenir exactement une ligne (par exemple, DUAL
dans Oracle) à l'aide de la clause ON
pour simuler la clause antérieure WHERE
. De telles constructions seraient artificielles; il serait évident que quelque chose manquait dans la langue et la situation serait pire.
TL; DR nous pourrions perdre HAVING
demain et la situation ne serait pas pire, voire meilleure, mais on ne peut pas en dire autant de WHERE
.
D'après les réponses, il semble que beaucoup de gens ne se rendent pas compte qu'une clause HAVING
peut être utilisée sans une clause GROUP BY
. Dans ce cas, la clause HAVING
est appliquée à l'ensemble de l'expression de la table et nécessite que seules les constantes apparaissent dans la clause SELECT
. Typiquement, la clause HAVING
impliquera des agrégats.
C'est plus utile que ça en a l'air. Par exemple, considérons cette requête pour tester si la colonne name
est unique pour toutes les valeurs de T
:
SELECT 1 AS result
FROM T
HAVING COUNT( DISTINCT name ) = COUNT( name );
Il n'y a que deux résultats possibles: si la clause HAVING
est vraie, le résultat sera une seule ligne contenant la valeur 1
, sinon le résultat sera l'ensemble vide.
La différence entre les deux réside dans la relation à la clause GROUP BY:
O vient avant GROUP BY; SQL évalue la clause WHERE avant de regrouper les enregistrements.
AVANT vient après GROUP BY; SQL évalue HAVING après le regroupement des enregistrements.
Références
La clause HAVING a été ajoutée à SQL car le mot clé WHERE n'a pas pu être utilisé avec des fonctions d'agrégat.
Découvrez ceci lien w3schools pour plus d'informations
Syntaxe:
SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value
Une requête telle que celle-ci:
SELECT column_name, COUNT( column_name ) AS column_name_tally
FROM table_name
WHERE column_name < 3
GROUP
BY column_name
HAVING COUNT( column_name ) >= 3;
... peut être réécrit en utilisant une table dérivée (et en omettant le HAVING
) comme ceci:
SELECT column_name, column_name_tally
FROM (
SELECT column_name, COUNT(column_name) AS column_name_tally
FROM table_name
WHERE column_name < 3
GROUP
BY column_name
) pointless_range_variable_required_here
WHERE column_name_tally >= 3;
HAVING
est utilisé lorsque vous utilisez un agrégat tel que GROUP BY
.
SELECT edc_country, COUNT(*)
FROM Ed_Centers
GROUP BY edc_country
HAVING COUNT(*) > 1
ORDER BY edc_country;
WHERE est appliqué en tant que limitation de l'ensemble renvoyé par SQL; il utilise les instructions et les index de l'ensemble intégré de SQL et constitue donc le moyen le plus rapide de filtrer les ensembles de résultats. Toujours utiliser WHERE chaque fois que possible.
HAVING est nécessaire pour certains filtres agrégés. Il filtre la requête APRÈS que sql ait récupéré, assemblé et trié les résultats. Par conséquent, il est beaucoup plus lent que WHERE et doit être évité, sauf dans les situations qui l'exigent.
SQL Server vous permettra d'utiliser HAVING même lorsque WHERE serait beaucoup plus rapide. Ne le fais pas.
La clause WHERE ne fonctionne pas pour les fonctions d'agrégat
signifie: vous ne devriez pas utiliser comme ce bonus: nom de la table
SELECT name
FROM bonus
GROUP BY name
WHERE sum(salary) > 200
HERE Au lieu d'utiliser la clause WHERE, vous devez utiliser HAVING ..
sans utiliser la clause GROUP BY, la clause HAVING fonctionne comme une clause WHERE
SELECT name
FROM bonus
GROUP BY name
HAVING sum(salary) > 200
Différence n/b WHERE
et HAVING
clause:
La principale différence entre les clauses WHERE
et HAVING
est que WHERE
est utilisé pour les opérations de ligne et HAVING
pour les opérations de colonne.
Pourquoi avons-nous besoin de la clause HAVING
?
Comme nous le savons, les fonctions d'agrégat ne peuvent être exécutées que sur des colonnes. Nous ne pouvons donc pas utiliser de fonctions d'agrégat dans la clause WHERE
. Par conséquent, nous utilisons des fonctions d'agrégat dans la clause HAVING
.
Lorsque GROUP BY
n'est pas utilisé, les clauses WHERE
et HAVING
sont essentiellement équivalentes.
Cependant, lorsque GROUP BY
est utilisé:
WHERE
est utilisée pour filtrer les enregistrements d'un résultat. Le filtrage a lieu avant tout regroupement.HAVING
est utilisée pour filtrer les valeurs d’un groupe (c’est-à-dire pour vérifier les conditions après l’agrégation dans des groupes).Ressource de ici
J'ai eu un problème et j'ai découvert une autre différence entre WHERE
et HAVING
. Il n’agit pas de la même manière sur les colonnes indexées.
WHERE my_indexed_row = 123
affichera les lignes et exécutera automatiquement un "ORDER ASC" sur les autres lignes indexées.
HAVING my_indexed_row = 123
affiche tout, de la plus ancienne rangée "insérée" à la plus récente, sans ordre.
Une façon de penser à cela est que la clause having constitue un filtre supplémentaire à la clause where.
Une clause OÙ est utilisée pour filtrer les enregistrements d'un résultat. Le filtre se produit avant que des groupements ne soient faits. Une clause HAVING est utilisée pour filtrer les valeurs d'un groupe
Dans une requête agrégée, (Toute requête dans laquelle une fonction d'agrégat est utilisée)
Les prédicats dans une clause Having sont appliqués à l'ensemble de résultats APRÈS qu'il ait été généré. C'est pourquoi les conditions de prédiction sur les valeurs agrégées doivent être placées dans la clause Having, et non dans la clause Where, et vous pouvez utiliser les alias définis dans la clause Select dans une clause having, mais pas dans une clause Where.
La clause WHERE est utilisée pour comparer les valeurs de la table de base, tandis que la clause HAVING peut être utilisée pour filtrer les résultats des fonctions d'agrégat dans le jeu de résultats de la requête. Cliquez ici !
Il se peut simplement que le sujet de "où" soit une rangée, alors que le sujet de "avoir" est un groupe. Ai-je raison?
Pendant que je travaillais sur un projet, c’était aussi ma question. Comme indiqué ci-dessus, le HAVING vérifie la condition du résultat de la requête déjà trouvé. Mais OÙ sert à vérifier la condition pendant l'exécution de la requête.
Laissez-moi vous donner un exemple pour illustrer cela. Supposons que vous ayez une table de base de données comme celle-ci.
usertable {int id utilisateur, date datefield, int dailyincome}
Supposons que les lignes suivantes sont dans la table:
1, 2011-05-20, 100
1, 2011-05-21, 50
1, 2011-05-30, 10
2, 2011-05-30, 10
2, 2011-05-20, 20
Maintenant, nous voulons obtenir le userid
s et sum(dailyincome)
dont sum(dailyincome)>100
Si nous écrivons:
SELECT ID utilisateur, somme (revenu quotidien) FROM utilisable WHERE somme (revenu quotidien)> 100 GROUP BY id utilisateur
Ce sera une erreur. La requête correcte serait:
SELECT ID utilisateur, somme (revenu quotidien) FROM utilisable GROUP BY, ID utilisateur ayant la somme (revenu quotidien)> 100
J'utilise HAVING pour contraindre une requête en fonction des résultats d'une fonction d'agrégat. PAR EXEMPLE. sélectionnez * dans le groupe blahblahblah par quelque chose qui compte (QUELQUE CHOSE)> 0
De ici .
le standard SQL exige que HAVING ne fasse référence qu'à des colonnes de la clause GROUP BY ou à des colonnes utilisées dans des fonctions d'agrégat
par opposition à la clause WHERE qui est appliquée aux lignes de la base de données