トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
10-48 最後に0になった日からの件数
SQLパズル
販売履歴テーブル
商品コード 販売日 販売数
---------- ---------- ------
11111 2003/10/28 90
11111 2003/10/25 30
11111 2003/10/23 0
11111 2003/10/22 10
11111 2003/10/21 0
11111 2003/10/20 10
22222 2003/10/22 10
商品コードごとの、
販売数が、最後に0になった日からのレコード数を出力する
販売数が0になった日がない場合は、その商品コードのレコード数を出力する
出力結果
商品コード 件数
---------- ----
11111 2
22222 1
データ作成スクリプト
create table 販売履歴(
商品コード char(5),
販売日 date,
販売数 number(2));
insert into 販売履歴 values('11111',to_date('2003/10/28','YYYY/MM/DD'),90);
insert into 販売履歴 values('11111',to_date('2003/10/25','YYYY/MM/DD'),30);
insert into 販売履歴 values('11111',to_date('2003/10/23','YYYY/MM/DD'), 0);
insert into 販売履歴 values('11111',to_date('2003/10/22','YYYY/MM/DD'),10);
insert into 販売履歴 values('11111',to_date('2003/10/21','YYYY/MM/DD'), 0);
insert into 販売履歴 values('11111',to_date('2003/10/20','YYYY/MM/DD'),10);
insert into 販売履歴 values('22222',to_date('2003/10/22','YYYY/MM/DD'),10);
commit;
SQL
--■■■相関サブクエリを使う方法1■■■
select 商品コード,count(*) as 件数
from 販売履歴 a
where 販売日 > (select max(b.販売日) from 販売履歴 b
where b.商品コード = a.商品コード
and b.販売数 = 0)
or not exists(select 1 from 販売履歴 b
where b.商品コード = a.商品コード
and b.販売数 = 0)
group by 商品コード
order by 商品コード;
--■■■相関サブクエリを使う方法2■■■
select 商品コード,count(*) as 件数
from 販売履歴 a
where not exists(select 1 from 販売履歴 b
where b.商品コード = a.商品コード
and b.販売日 >= a.販売日
and b.販売数 = 0)
group by 商品コード
order by 商品コード;
--■■■分析関数を使う方法■■■
select 商品コード,count(*) as 件数
from (select 商品コード,販売日,
max(decode(販売数,0,販売日)) over(partition by 商品コード) as 販売数が0の日
from 販売履歴)
where 販売日 > 販売数が0の日
or 販売数が0の日 is null
group by 商品コード
order by 商品コード;
--■■■分析関数とignore nullsを使う方法1(10g以降)■■■
select 商品コード,count(*) as 件数
from (select 商品コード,販売日,
Last_Value(decode(販売数,0,販売日) ignore nulls)
over(partition by 商品コード order by 販売日
Rows between Unbounded Preceding and Unbounded Following) as 販売数が0の日
from 販売履歴)
where 販売日 > 販売数が0の日
or 販売数が0の日 is null
group by 商品コード
order by 商品コード;
--■■■分析関数とignore nullsを使う方法2(10g以降)■■■
select 商品コード,sum(IsCount) as 件数
from (select 商品コード,
case when 販売日 <=
Last_Value(decode(販売数,0,販売日) ignore nulls)
over(partition by 商品コード order by 販売日
Rows between Unbounded Preceding and Unbounded Following)
then 0 else 1 end as IsCount
from 販売履歴)
group by 商品コード
order by 商品コード;
解説
分析関数を使う方法では、
Max関数とdecode関数を組み合わせて、
販売数が0の日のなかで、最大の日を取得してます。