2. IDごとのValの累計を求める
次は、IDごとValの累計を求めるSQLについてです。まずは、テーブルのデータと、出力結果を考えます。
ID | Seq | Val |
AA | 1 | 100 |
AA | 2 | 100 |
AA | 3 | 500 |
AA | 4 | 200 |
AA | 5 | 200 |
AA | 6 | 50 |
BB | 1 | 200 |
BB | 2 | 400 |
BB | 3 | 800 |
BB | 4 | 900 |
CC | 1 | 100 |
CC | 2 | 800 |
CC | 3 | 700 |
DD | 1 | 400 |
EE | 1 | 50 |
FF | 1 | 10 |
FF | 3 | 20 |
FF | 5 | 40 |
FF | 6 | 80 |
IDごとに、Seqの昇順でのValの累計を求めます。言いかえれば、Oracleの下記の分析関数を使ったSQLと同じ結果を取得します。
select ID,Seq,Val, sum(Val) over(partition by ID order by Seq) as sumVal2 from IDTable order by ID,Seq;
ID | Seq | Val | sumVal2 |
AA | 1 | 100 | 100 |
AA | 2 | 100 | 200 |
AA | 3 | 500 | 700 |
AA | 4 | 200 | 900 |
AA | 5 | 200 | 1100 |
AA | 6 | 50 | 1150 |
BB | 1 | 200 | 200 |
BB | 2 | 400 | 600 |
BB | 3 | 800 | 1400 |
BB | 4 | 900 | 2300 |
CC | 1 | 100 | 100 |
CC | 2 | 800 | 900 |
CC | 3 | 700 | 1600 |
DD | 1 | 400 | 400 |
EE | 1 | 50 | 50 |
FF | 1 | 10 | 10 |
FF | 3 | 20 | 30 |
FF | 5 | 40 | 70 |
FF | 6 | 80 | 150 |
累計は、同じIDでSeqが自分以下の行のValの合計だと考えて、答えは下記となります。
select ID,Seq,Val, (select sum(b.Val) from IDTable b where b.ID = a.ID and b.Seq <= a.Seq) as sumVal2 from IDTable a order by ID,Seq;
前問と似た考え方を使っていて、相関サブクエリでwhere b.ID = a.ID
を指定して、外側のselect
文の結果と同じIDを条件として、さらに、Seqが自分以下であることを条件として、sum
関数でValの合計を求めています。結果としてIDごとのSeqの昇順でのValの累計が求まります。
SQLのイメージは下記となります。
![SQLのイメージ SQLのイメージ](http://cz-cdn.shoeisha.jp/static/images/article/3107/fig02a.gif)