トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

7-40 指定した範囲のデータを取得

SQLパズル

販売テーブル
日付           連番
-------------  ----
2005/05/01 10     1
2005/05/01 20     2
2005/05/01 22     3
2005/05/02 10     1
2005/05/02 15     2
2005/05/02 17     3
2005/05/03 15     1
2005/05/03 19     2
2005/05/03 23     3

販売テーブルの
2005/05/01の連番3から、
2005/05/03の連番1までのデータを取得する。

出力結果
日付           連番
-------------  ----
2005/05/01 22     3
2005/05/02 10     1
2005/05/02 15     2
2005/05/02 17     3
2005/05/03 15     1


データ作成スクリプト

create table 販売(
日付 date,
連番 number(1));

insert into 販売 values(to_date('2005/05/01 10','YYYY/MM/DD HH24'),1);
insert into 販売 values(to_date('2005/05/01 20','YYYY/MM/DD HH24'),2);
insert into 販売 values(to_date('2005/05/01 22','YYYY/MM/DD HH24'),3);
insert into 販売 values(to_date('2005/05/02 10','YYYY/MM/DD HH24'),1);
insert into 販売 values(to_date('2005/05/02 15','YYYY/MM/DD HH24'),2);
insert into 販売 values(to_date('2005/05/02 17','YYYY/MM/DD HH24'),3);
insert into 販売 values(to_date('2005/05/03 15','YYYY/MM/DD HH24'),1);
insert into 販売 values(to_date('2005/05/03 19','YYYY/MM/DD HH24'),2);
insert into 販売 values(to_date('2005/05/03 23','YYYY/MM/DD HH24'),3);
commit;


SQL

--■■■orを複数回使う方法■■■
select to_char(日付,'YYYY/MM/DD HH24') as 日付,連番
from 販売
where (to_char(日付,'YYYY/MM/DD') ='2005/05/01' and 連番 >=3)
   or ((to_date('2005/05/01','YYYY/MM/DD') < trunc(日付)
       and trunc(日付) < to_date('2005/05/03','YYYY/MM/DD')))
   or (to_char(日付,'YYYY/MM/DD') ='2005/05/03' and 連番 <=1);

--■■■having句でrank withinを使う方法■■■
select to_char(日付,'YYYY/MM/DD HH24') as 日付,連番
  from 販売 a
 where exists(select 1 from 販売 b
              having rank(trunc(a.日付),a.連番) within group(order by trunc(b.日付),b.連番)
             between rank(date '2005-05-01',3)  within group(order by trunc(b.日付),b.連番)
                 and rank(date '2005-05-03',1)  within group(order by trunc(b.日付),b.連番));


解説

3つの条件に分けて、orを使ってます。

5-60 having句でrank within