rm /blog

IT系技術職のおっさんがIT技術とかライブとか日常とか雑多に語るブログです。* 本ブログに書かれている内容は個人の意見・感想であり、特定の組織に属するものではありません。/All opinions are my own.*

【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の使い方を覚えてなかっただけであるが)。