web-dev-qa-db-fra.com

Quelle est la différence entre HAVING et WHERE?

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 clause WHERE.

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.

253
ColinYounger

HAVING spécifie une condition de recherche pour un groupe ou une fonction d'agrégat utilisée dans l'instruction SELECT.

Source

89
Steven

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.

343
wcm

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.

26
onedaywhen

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.

select statement diagram

Références

21
Paul Sweatte

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;
21
Kaiser Advisor

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;
12
Galwegian

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.

8
davidcl

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.

4
M Asad Ali

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 filtrage a lieu avant tout regroupement.
  • 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 dans des groupes).

Ressource de ici

3
bebosh

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.

2
Simmoniz

Une façon de penser à cela est que la clause having constitue un filtre supplémentaire à la clause where.

Une clause 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

2
Ved Prakash

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.

1
Charles Bretana

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 !

1
Muhammad Ali

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?

0
Viky Leaf

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 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 userids 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

0
Nayan

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

0
JasonTrue

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

0
Harry Lime