Was ist der Unterschied zwischen WHERE und HAVING Klauseln?

In diesem Artikel erfahren Sie, wann WO und MIT. Beide führen ähnliche Funktionen aus, aber für unterschiedliche Zwecke!

Alle Beispiele für diesen Artikel basieren auf Microsoft SQL Server Management Studio und der AdventureWorks2012-Datenbank. Sie können mit diesen kostenlosen Tools beginnen, indem Sie meinen Leitfaden Erste Schritte mit SQL Server verwenden.

Wie unterscheiden sich Wo und Wie?

Bei der Arbeit mit fortgeschrittenem SQL kann es unklar sein, wann es sinnvoll ist, eine WHERE- gegenüber einer HAVING-Klausel zu verwenden.

Obwohl es scheint, dass beide Klauseln dasselbe tun, tun sie es auf unterschiedliche Weise. Tatsächlich ergänzen sich ihre Funktionen.

  • Eine WHERE-Klausel wird verwendet, um Datensätze aus einem Ergebnis zu filtern. Der Filter tritt auf, bevor Gruppierungen vorgenommen werden.
  • Eine HAVING-Klausel wird verwendet, um Werte aus einer Gruppe zu filtern.

Bevor wir weiter gehen, überprüfen wir das Format einer SQL-Anweisung. Es ist

SELECTFROMWHEREGROUP BYHAVING

Um die Dinge gerade zu halten, denke ich gerne an die Reihenfolge der Ausführung von SQL-Anweisungen von oben nach unten. Das bedeutet, dass die WHERE-Klausel zuerst auf das Ergebnis angewendet wird und dann die verbleibenden Zeilen gemäß GROUP BY zusammengefasst werden.

WHERE-Klausel

Die WHERE-Klausel wird verwendet, um Zeilen aus Ergebnissen zu filtern. Zum Beispiel Gibt

SELECT COUNT(SalesOrderID)FROM Sales.SalesOrderDetail

121.317 als Zählung zurück, während die Abfrage

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

48.159 als Zählung zurückgibt. Dies liegt daran, dass die WHERE-Klausel die 73.158 SalesOrderDetails, deren UnitPrice kleiner oder gleich 200 ist, aus den Ergebnissen herausfiltert.

HAVING-Klausel

Die HAVING-Klausel wird verwendet, um Werte in einer GROUP BY zu filtern. Sie können sie verwenden, um Gruppen wie

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

herauszufiltern, aber ihre wahre Stärke liegt in ihrer Fähigkeit, basierend auf aggregierten Funktionsergebnissen zu vergleichen und zu filtern. Sie können beispielsweise alle Bestellungen auswählen, die mehr als $10,000

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

Da die Sichtbarkeit der WHERE-Klausel jeweils eine Zeile beträgt, kann die SUMME nicht über alle salesorderids hinweg ausgewertet werden. Die HAVING-Klausel wird ausgewertet, nachdem die Gruppierung erstellt wurde.

Die Kombination der beiden: WHERE und HAVING

Wenn SQL-Anweisungen sowohl eine WHERE-Klausel als auch eine HAVING-Klausel enthalten, beachten Sie, dass die WHERE-Klausel zuerst angewendet, dann die Ergebnisse gruppiert und schließlich die Gruppen gemäß der HAVING-Klausel gefiltert werden.

In vielen Fällen können Sie die WHERE-Bedingung in die HAVING-Klausel einfügen, z. B.

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

Versus

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

Wenn Sie eine Bedingung aus der where-Klausel in die having-Klausel einfügen können, warum sollten Sie sich dann überhaupt Gedanken über das WHERE machen? Kann ich diese Abfrage einfach verwenden?

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

Tatsächlich generiert diese Abfrage einen Fehler. Die Spalte LineTotal ist weder Teil der Feldliste group by noch das Ergebnis einer Gesamtsumme.

Um gültig zu sein, kann die having Klausel nur Ergebnisse von aggregierten Funktionen oder Spaltenteilen der group by vergleichen.

Um gültig zu sein, muss die Abfrage als

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

umgeschrieben werden, um den Unterschied zwischen WHERE und HAVING zusammenzufassen:

  • WHERE wird verwendet, um Datensätze zu filtern, bevor Gruppierungen stattfinden.
  • HAVING wird verwendet, um Werte zu filtern, nachdem sie gruppiert wurden. Nur Spalten oder Ausdrücke in der Gruppe können in die Bedingungen der HAVING-Klausel aufgenommen werden…

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.

More: