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