グループ化したデータをHAVING句で絞り込む:さらっと覚えるSQL&T-SQL入門(5)(1/3 ページ)
アプリケーション開発でデータベースを利用する新人プログラマに向けて、SQLおよびT-SQLを短期間で理解できるよう、開発現場ですぐに必要となる内容を中心に解説する。(編集部)
主な内容
--Page 1--
▼グループ化した結果を絞り込むHAVING句
▼WHERE句とHAVING句の違い
--Page 2--
▼HAVING句でグループ化した結果を絞り込む
▼HAVING句と論理演算子の組み合わせ
--Page 3--
▼HAVING句を利用する際の注意点
▼まとめ
第5回を迎えた本連載ですが、過去4回の連載を経て内容が徐々に濃くなってきました。単純なSELECT文から始まり、関数の利用、グループ化による集計などをこれまでに取り上げています。今回は、前回取り上げた「GROUP BY」句によるグループ化機能の利便性をさらに高める「HAVING」句を取り上げます。
グループ化した結果を絞り込むHAVING句
HAVING句を利用すると、GROUP BY句によってグループ化されたデータに対し、検索条件を指定し絞り込むことが可能です。絞り込みといえば「WHERE」句も絞り込みを行いますが、WHERE句はグループ化されたデータに対して絞り込みを行うことはできません。WHERE句とGROUP BY句を併用した場合、WHERE → GROUP BYの順でクエリが評価されるため、グループ化された結果をWHERE句の段階で利用できないのです。
この問題に対し、HAVING句とGROUP BY句を利用した場合、GROUP BY → HAVINGの順でクエリが評価され、グループ化された結果に対し条件を指定することが可能です。
HAVING句は次のように記述します([ ]カッコは省略可能であることを示します)。
SELECT 列名 FROM 表名 [WHERE 条件] GROUP BY 列名 HAVING 条件
では実際の動きを見ながら、HAVING句を利用してみましょう。
WHERE句とHAVING句の違い
サンプルデータベースのAdventureWorksに含まれるSalesOrderHeaderテーブルを利用したSQLの発行を行いましょう。まずはGROUP BY句を利用して顧客ごとの平均受注額を求めます。
SELECT CustomerID,AVG(TotalDue) AS 平均支払額 FROM Sales.SalesOrderHeader GROUP BY CustomerID 結果 CustomerID 平均支払額 ----------- --------------------- 14324 1886.3927 22814 5.514 11407 59.659 …中略… 24886 88.9194 21640 136.9758
上記の結果のうち、平均支払額が1000以上の顧客を求めてみましょう。上記のSQLに対し、「平均支払額が1000以上」という条件を加えればよいことになります。しかしながら、単純にWHERE句に加えてしまうとエラーになってしまいます。
SELECT CustomerID,AVG(TotalDue) AS 平均支払額 FROM Sales.SalesOrderHeader WHERE AVG(TotalDue) >= 1000 GROUP BY CustomerID 結果 メッセージ 147、レベル 15、状態 1、行 1 集計がHAVING句または選択リスト内のサブクエリにある場合、および集計する列が外部参照の場合にだけ、WHERE句に集計を含めることができます。
WHERE句にて集計関数であるAVG関数の結果に対して条件を指定していますが、実行結果はエラーとなります。SQL文の評価はWHERE句、GROUP BY句の順で行われるため、GROUP BY句によるグループ化した結果を利用する集計関数に対してWHERE句による条件指定を行うことはできないためです。
Copyright © ITmedia, Inc. All Rights Reserved.