この記事では、いつWHEREとHAVINGを使用するかを学びます。 どちらも同様の機能を実行しますが、異なる目的のために!
この記事のすべての例は、Microsoft SQL Server Management StudioおよびAdventureworks2012データベースに基づいています。 あなたは、SQL Serverの使用を開始する私のガイドを使用して、これらの無料のツールを使用して開始することができます。
どのようにどこと異なるのですか?より高度なSQLを使用する場合、WHERE句とHAVING句を使用するのが理にかなっているかどうかが不明になる可能性があります。
両方の句が同じことをするように見えますが、異なる方法でそれを行います。 実際、それらの機能は互いに補完し合っています。
- WHERE句が使用されるのは、結果からレコードをフィルタリングすることです。 フィルタは、グループ化が行われる前に実行されます。
- HAVING句は、グループの値をフィルタリングするために使用されます。
先に進む前に、SQL文の形式を確認してみましょう。 物事をまっすぐに保つのを助けるのは
SELECTFROMWHEREGROUP BYHAVING
SQL文の実行順序を上から下に考えるのが好きです。 つまり、WHERE句が最初に結果に適用され、次に残りの行がGROUP BYに従って要約されることを意味します。
WHERE句
WHERE句は、結果から行をフィルタリングするために使用されます。 たとえば、
SELECT COUNT(SalesOrderID)FROM Sales.SalesOrderDetail
はカウントの時点で121,317を返しますが、クエリ
SELECT COUNT(SalesOrderID)FROM Sales.SalesOrderDetailWHERE UnitPrice > 200
はカウントとして48,159を返します。 これは、WHERE句によって、Unitpriceが結果から200以下の73,158SalesOrderDetailsが除外されるためです。
HAVING句
HAVING句は、GROUP BYの値をフィルタリングするために使用されます。 それらを使用して、
SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailGROUP BY SalesOrderIDHAVING SalesOrderID > 50000
などのグループを除外できますが、その真の力は、集計関数の結果に基づいて比較およびフィルタリングできることにあります。 たとえば、以下の合計を超えるすべての注文を選択できます$10,000
SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailGROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000
WHERE句の可視性は一度に1行ずつであるため、すべてのSalesOrderIDの合計を評価する方法はありません。HAVING句はグループ化が作成された後に評価されます。
: WHERE and HAVING
SQL文にWHERE句とHAVING句の両方がある場合は、最初にWHERE句が適用され、次に結果がグループ化され、最後にhaving句に従ってグループがフィルタリングされ
多くの場合、
SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailGROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000 AND SalesOrderID > 50000
と
SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailWHERE SalesOrderID > 50000GROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000
のように、HAVING句にWHERE条件を配置できますwhere句の条件をhaving句に入れることができれば、WHERE句を心配するのはなぜですか? このクエリを使用できますか?
SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailGROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000 AND LineTotal > 10
実際にはそのクエリはエラーを生成します。 列LineTotalは、group byフィールドリストの一部でも、集計合計の結果でもありません。
有効であるために、having句は、集計された関数またはgroup byの列部分の結果のみを比較できます。クエリを有効にするには、WHEREとHAVINGの違いを要約するために、クエリを
SELECT SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPriceFROM Sales.SalesOrderDetailWHERE LineTotal > 100GROUP BY SalesOrderIDHAVING SUM(UnitPrice * OrderQty) > 10000
として書き直す必要があります:
- WHEREは、グループ化が行われる前にレコードをフィルター処理するために使用されます。
- HAVINGは、グループ化された後の値をフィルタリングするために使用されます。 HAVING句の条件に含めることができるのは、グループ内の列または式のみです…