Quelle est la différence entre les clauses WHERE et HAVING?

Dans cet article, apprenez quand utiliser OÙ et AVOIR. Les deux remplissent des fonctions similaires, mais à des fins différentes!

Tous les exemples de cet article sont basés sur Microsoft SQL Server Management Studio et la base de données AdventureWorks2012. Vous pouvez commencer à utiliser ces outils gratuits en utilisant mon Guide Pour commencer à utiliser SQL Server.

En quoi l’Endroit et l’Avoir Diffèrent-ils?

Lorsque vous travaillez avec du SQL plus avancé, il peut être difficile de savoir quand il est logique d’utiliser une clause WHERE par rapport à une clause HAVING.

Bien qu’il semble que les deux clauses fassent la même chose, elles le font de différentes manières. En fait, leurs fonctions se complètent.

  • Une clause WHERE est utilisée pour filtrer les enregistrements d’un résultat. Le filtre se produit avant que des regroupements ne soient effectués.
  • Une clause HAVING est utilisée pour filtrer les valeurs d’un groupe.

Avant d’aller plus loin, passons en revue le format d’une instruction SQL. C’est

SELECTFROMWHEREGROUP BYHAVING

Pour aider à garder les choses droites, j’aime penser à l’ordre d’exécution des instructions SQL de haut en bas. Cela signifie que la clause WHERE est d’abord appliquée au résultat, puis les lignes restantes résumées en fonction du GROUPE PAR.

Clause WHERE

La clause WHERE est utilisée pour filtrer les lignes des résultats. Par exemple,

SELECT COUNT(SalesOrderID)FROM Sales.SalesOrderDetail

Renvoie 121 317 à partir du nombre, tandis que la requête

SELECT COUNT(SalesOrderID)FROM Sales.SalesOrderDetailWHERE UnitPrice > 200

Renvoie 48 159 comme nombre. Cela est dû à la clause WHERE qui filtre les 73 158 SalesOrderDetails dont le prix unitaire est inférieur ou égal à 200 à partir des résultats.

Clause HAVING

La clause HAVING est utilisée pour filtrer les valeurs d’un GROUPE PAR. Vous pouvez les utiliser pour filtrer des groupes tels que

SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailGROUP BY SalesOrderIDHAVING SalesOrderID > 50000

, Mais leur véritable pouvoir réside dans leur capacité à comparer et à filtrer en fonction des résultats des fonctions agrégées. Par exemple, vous pouvez sélectionner toutes les commandes totalisant plus de $10,000

SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailGROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000

Étant donné que la visibilité de la clause WHERE est une ligne à la fois, il n’y a aucun moyen pour elle d’évaluer la SOMME de tous les SalesOrderID. La clause HAVING est évaluée après la création du regroupement.

Combiner les deux: WHERE et HAVING

Lorsque les instructions SQL ont à la fois une clause WHERE et une clause HAVING, gardez à l’esprit que la clause WHERE est d’abord appliquée, puis les résultats regroupés et enfin, les groupes filtrés en fonction de la clause HAVING.

Dans de nombreux cas, vous pouvez placer la condition WHERE dans la clause HAVING, telle que

SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailGROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000 AND SalesOrderID > 50000

Par rapport à

SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailWHERE SalesOrderID > 50000GROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000

Si vous pouvez mettre la condition de la clause where dans la clause having, alors pourquoi même vous soucier du WHERE? Puis-je simplement utiliser cette requête?

SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailGROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000 AND LineTotal > 10

En fait, cette requête génère une erreur. La colonne LineTotal ne fait pas partie de la liste des champs groupés par, ni du résultat d’un total global.

Pour être valide, la clause having ne peut comparer que les résultats de fonctions agrégées ou d’une partie de colonne du groupe par.

Pour être valide, la requête doit être réécrite en tant que

SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailWHERE LineTotal > 100GROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000

Pour résumer la différence entre WHERE et HAVING:

  • OÙ est utilisé pour filtrer les enregistrements avant tout regroupement.
  • HAVING est utilisé pour filtrer les valeurs après qu’elles ont été des groupes. Seules les colonnes ou expressions du groupe peuvent être incluses dans les conditions de la clause HAVING

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.

More: