トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
7-64 カレンダーテーブルと結合
SQLパズル
カレンダーテーブル
日付
----------
2006/01/01
2006/01/02
・・・・
2006/12/30
2006/12/31
売上テーブル
ID 日付 数量
-- ---------- ----
A 2006/02/01 100
A 2006/02/03 200
A 2006/02/05 300
B 2006/03/01 100
B 2006/03/04 200
売上テーブルの、IDごとに、
カレンダーテーブルと結合して、
以下の出力をする。
出力結果
ID 日付 数量
-- ---------- ----
A 2006/02/01 100
A 2006/02/02 0
A 2006/02/03 200
A 2006/02/04 0
A 2006/02/05 300
B 2006/03/01 100
B 2006/03/02 0
B 2006/03/03 0
B 2006/03/04 200
データ作成スクリプト
create table カレンダー as
select to_date('20060101','yyyymmdd')+RowNum-1 as 日付
from all_catalog
where to_date('20060101','yyyymmdd')+RowNum-1 < to_date('20070101','yyyymmdd');
create table 売上(
ID char(1),
日付 date,
数量 number(3));
insert into 売上 values('A',to_date('2006/02/01','yyyy/mm/dd'),100);
insert into 売上 values('A',to_date('2006/02/03','yyyy/mm/dd'),200);
insert into 売上 values('A',to_date('2006/02/05','yyyy/mm/dd'),300);
insert into 売上 values('B',to_date('2006/03/01','yyyy/mm/dd'),100);
insert into 売上 values('B',to_date('2006/03/04','yyyy/mm/dd'),200);
commit;
SQL
--■■■nvl関数を使う方法■■■
select a.ID,b.日付,
decode(a.日付,b.日付,a.数量,0) as 数量
from (select ID,数量,日付,
nvl(Lead(日付-1) over(partition by ID order by 日付),日付) as Lead日付
from 売上) a,カレンダー b
where b.日付 between a.日付 and a.Lead日付;
--■■■nvl関数を使わない方法■■■
select a.ID,b.日付,
decode(a.日付,b.日付,a.数量,0) as 数量
from (select ID,数量,日付,
Lead(日付-1,1,日付) over(partition by ID order by 日付) as Lead日付
from 売上) a,カレンダー b
where b.日付 between a.日付 and a.Lead日付;
解説
Lead関数で次の日付を取得してます。