【Oracle】group byで使う条件句「having」について
havingは、group byで集計する時に一緒に使える条件句である。
個人的には、group by部分を副問い合わせにしちまって外側でwhere句で絞り込む方が多いのだが、
集計すると同時に絞り込めるという点では、SQLがシンプルになってよいのだろう。
使い方の備忘録として残す。
下記のようなテーブルデータ(TEST_URIAGEテーブルとする)があったとする。
NoUDateUriage
1 | 2016/12/02 | ¥1,200 |
2 | 2016/12/02 | ¥1,000 |
3 | 2016/12/10 | ¥500 |
4 | 2016/12/10 | ¥200 |
5 | 2016/12/21 | ¥2,300 |
6 | 2016/12/21 | ¥2,100 |
このテーブルに対して「UDateでGroup ByしてUriageをSUMし、SUMしたUriageが¥1000以上」となるような抽出を行いたい場合
select
TEST_URIAGE.UDATE
,count(1) rec
,sum(TEST_URIAGE.URIAGE) as URIAGE
from TEST_URIAGE
group by
TEST_URIAGE.UDATE
having sum(TEST_URIAGE.URIAGE) >= 1000
とすれば、条件に見合うレコードだけが抽出される。
UdateでGroup Byすると、No.1-2、No.3-4、No.5-6は集約される形になるので、
havingの条件なしだと合計3行が返却結果となるのだが、
(1)No.1-2のSUM(URIAGE)は¥1,200+¥1,000=¥2,200←¥1,000以上なので抽出対象
(2)No.3-4のSUM(URIAGE)は¥500+¥200=¥700←¥1,000未満なので対象外
(3)No.5-6のSUM(URIAGE)は¥2,300+¥2,100=¥4,400←¥1,000以上なので抽出対象
となって(1)(3)の2レコードだけが結果に表れる形になる。
ちなみに冒頭書いたように”group by部分を副問い合わせにしちまって外側でwhere句で絞り込む”でも出来る↓
select x.* from ( select TEST_URIAGE.UDATE ,count(1) rec ,sum(TEST_URIAGE.URIAGE) as URIAGE from TEST_URIAGE group by TEST_URIAGE.UDATE ) x where x.URIAGE >= 1000
個人的にはこっち派(単にhavingの使い方を覚えてなかっただけであるが)。