【SQL】HAVING:集約後の条件指定

  • #SQL

集合に対する条件を指定する

(前提:WHERE句は、グループに対して条件指定ができない)

  • HAVING句はGROUP BY句の後ろに書くこと

例①

/* HAVINGを使わない場合 */
SELECT shohin_bunrui, COUNT(*)
FROM Shohin
GROUP BY shohin_bunrui;

 shohin_bunrui | count 
---------------+-------
 キッチン用品  |     4
 衣服          |     2
 事務用品      |     2
/* HAVINGで条件指定(2行の商品分類を選択) */
SELECT shohin_bunrui, COUNT(*)
FROM Shohin
GROUP BY shohin_bunrui
HAVING COUNT(*) = 2;

/* キッチン用品が正しく除外された */
 shohin_bunrui | count 
---------------+-------
 衣服          |     2
 事務用品      |     2

例②

/* 商品分類の販売価格の平均を出す */
SELECT shohin_bunrui, AVG(hanbai_tanka)
FROM Shohin
GROUP BY shohin_bunrui;

 shohin_bunrui |          avg          
---------------+-----------------------
 キッチン用品  | 2795.0000000000000000
 衣服          | 2500.0000000000000000
 事務用品      |  300.0000000000000000
/* HAVINGで条件指定(平均が2500円以上) */
SELECT shohin_bunrui, AVG(hanbai_tanka)
FROM Shohin
GROUP BY shohin_bunrui
HAVING AVG(hanbai_tanka) >= 2500;

/* 事務用品が正しく除外された */
 shohin_bunrui |          avg          
---------------+-----------------------
 キッチン用品  | 2795.0000000000000000
 衣服          | 2500.0000000000000000

HAVING句に書ける要素

(GROUP BY句を使ったときのSELECTと全く同じ)

【OKな要素】

  • 定数
  • 集約関数
  • GROUP BY句で指定した列名(つまり集約キー)
/* NG */
SELECT shohin_bunrui, COUNT(*)
FROM Shohin
GROUP BY shohin_bunrui
HAVING shohin_mei = 'ボールペン';

ERROR:  column "shohin.shohin_mei" must appear in the GROUP BY clause or be used in an aggregate function
LINE 3: GROUP BY shohin_bunrui HAVING shohin_mei = 'ボールペン';
/* エラー内容
列"shohin.shohin_mei"は`GROUP BY`句で出現しなければならないか、
集約関数内で使用しなければなりません */
  • shohin_mei はGROUP BY句に含まれていない
  • HAVING句は、集約後を起点にして動いている

HAVING句よりもWHERE句に書いたほうが良い条件

例:条件の内容が同じ、かつ返ってくる結果も同じ

/* HAVINGで条件指定 */
SELECT shohin_bunrui, COUNT(*)
FROM Shohin
GROUP BY shohin_bunrui
HAVING shohin_bunrui = '衣服';

 shohin_bunrui | count 
---------------+-------
 衣服          |     2
/* WHEREで条件指定 */
SELECT shohin_bunrui, COUNT(*)
FROM Shohin
WHERE shohin_bunrui = '衣服' 
GROUP BY shohin_bunrui;

 shohin_bunrui | count 
---------------+-------
 衣服          |     2

HAVINGとWHEREの役割

句 役割
HAVING 「グループ」に対して条件指定するもの
WHERE 「行」に対して条件指定するもの

そのため上記の例では、WHERE句を使うほうが筋が通っている。

集約キーに対する条件指定はWHERE句に書く (集約キー:今回はshohin_bunrui)


関連記事:【SQL】GROUP BY:グループに切り分ける

参考書籍:ミック『SQL 第2版 ゼロからはじめるデータベース操作』(翔泳社)