検索
連載

グループ化したデータをHAVING句で絞り込むさらっと覚えるSQL&T-SQL入門(5)(1/3 ページ)

アプリケーション開発でデータベースを利用する新人プログラマに向けて、SQLおよびT-SQLを短期間で理解できるよう、開発現場ですぐに必要となる内容を中心に解説する。(編集部)

PC用表示
Share
Tweet
LINE
Hatena

主な内容

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

       | 次のページへ
ページトップに戻る