Quelle est la différence entre HAVING et WHERE?
Question
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 WHERE
ne comportait pas GROUP BY
et c'est là que ma confusion a commencé. Bien sûr, tant que vous ne le saurez pas, vous ne pourrez pas le préciser dans la question.
Merci beaucoup pour toutes les réponses très éclairantes.
La solution
HAVING spécifie une condition de recherche pour un groupe ou une fonction d'agrégat utilisée dans l'instruction SELECT.
Autres conseils
HAVING: est utilisé pour vérifier les conditions après la réalisation de l'agrégation.
WHERE: est utilisé pour vérifier les conditions avant que l'agrégation ait 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 l'État de Massachusetts 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 fournit un tableau des villes de l'État du Massachusetts comportant plus de 5 adresses et le nombre d'adresses dans chaque ville.
Première différence pour moi: si HAVING
était supprimé du langage SQL, la vie serait plus longue ou plus longue que précédemment. 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. Le code de l'optimiseur des vendeurs devrait peut-être être réécrit pour tenir compte de cela, ce qui serait encore une opportunité d'amélioration pour le secteur.
Pensez maintenant à supprimer 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 WHERE
précédente. De telles constructions seraient artificielles; il serait évident que quelque chose manquait dans la langue et la situation serait pire en conséquence.
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 fournies, 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'expression entière de la table et nécessite que seules les constantes apparaissent dans la clause SELECT
. La clause HAVING
implique généralement des agrégats.
Ceci est plus utile que ça en a l'air. Par exemple, considérez 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 est une seule ligne contenant la valeur 1
, sinon le résultat sera vide. définir.
La clause HAVING a été ajoutée à SQL car le mot clé WHERE n'a pas pu être utilisé avec les fonctions d'agrégat.
Découvrez ce 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 (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;
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.
-
HAVING vient après GROUP BY; SQL évalue HAVING après le regroupement des enregistrements.
Références
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 du jeu 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. Utilisez toujours WHERE dans la mesure du 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 cas où cela est nécessaire.
SQL Server vous laissera utiliser l’utilisation de 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 ça
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 b / w WHERE
et HAVING
:
La différence principale entre les clauses WHERE
et HAVING
est que WHERE
est utilisé pour les opérations sur les lignes et que HAVING
est utilisé pour les opérations sur les colonnes.
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. Par conséquent, nous ne pouvons 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é:
- La clause
WHERE
est utilisée pour filtrer les enregistrements d'un résultat. le le filtrage a lieu avant que des groupements ne soient faits. - La clause
HAVING
est utilisée pour filtrer les valeurs d'un groupe (c'est-à-dire, pour vérifier les conditions après l’agrégation en groupes).
Ressource de ici . p>
J'ai eu un problème et j'ai découvert une autre différence entre WHERE
et HAVING
. Cela n’agit pas de la même façon sur les colonnes indexées.
WHERE my_indexed_row = 123
affichera des lignes et effectuera automatiquement un " ORDER ASC " sur d'autres lignes indexées.
HAVING my_indexed_row = 123
affiche tout du plus ancien " inséré " rangée au plus récent, pas de commande.
Une façon de penser est que la clause having est un filtre supplémentaire à la clause where.
Une clause WHERE est utilisée pour filtrer les enregistrements d'un résultat. Le filtre se produit avant que des groupements soient faits. Une clause HAVING permet de 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 where sont évalués avant la génération du jeu de résultats intermédiaires agrégés,
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 sur ici . !
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 doit référencer uniquement les colonnes du Clause GROUP BY ou colonnes utilisées dans fonctions d'agrégat
par opposition à la clause WHERE appliquée aux lignes de la base de données
Alors que je travaillais sur un projet, c’était aussi ma question. Comme indiqué ci-dessus, HAVING vérifie la condition du résultat de la requête déjà trouvé. Mais WHERE 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 figurent dans le tableau:
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
Nous voulons maintenant obtenir les ID utilisateur
s et sum (dailyincome)
dont sum (dailyincome) > 100
Si nous écrivons:
SELECT userid, sum (dailyincome) FROM utilisable par 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 utilisateur ID HAVING somme (revenu quotidien)> 100
Il se peut simplement que le sujet "& where;" " est une ligne, alors que le sujet de "avoir" est un groupe. Ai-je raison?