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

9-6 行事の間に宿泊した客を取得その1

SQLパズル

宿泊者テーブル                    行事テーブル
Name     CheckIN    CheckOut     行事名    StartDay      EndDay
----  ----------  ----------     ------  ----------  ----------
Al    1999/02/01  1999/11/01     元旦    1999/01/01  1999/01/01
Ben   1999/12/10  1999/12/20     正月    1999/01/01  1999/01/03
Ed    1999/01/01  1999/11/11     七夕    1999/07/07  1999/07/07
Joe   1999/02/01  1999/02/28     大晦日  1999/12/31  1999/12/31
Ken   1999/12/01  1999/12/25

宿泊者テーブルと、行事テーブルから
行事の間に宿泊した客を出力する

出力結果
Name  行事名
----  ------
Al    七夕
Ed    元旦
Ed    正月
Ed    七夕

プログラマのためのSQL第2版の13章[betweenとOverLaps述語]を参考にさせていただきました


データ作成スクリプト

create table 宿泊者(
Name     char(3),
CheckIn  Date,
CheckOut Date);

insert into 宿泊者 values('Al' ,to_date('19990201','yyyymmdd'),to_date('19991101','yyyymmdd'));
insert into 宿泊者 values('Ben',to_date('19991210','yyyymmdd'),to_date('19991220','yyyymmdd'));
insert into 宿泊者 values('Ed' ,to_date('19990101','yyyymmdd'),to_date('19991111','yyyymmdd'));
insert into 宿泊者 values('Joe',to_date('19990201','yyyymmdd'),to_date('19990228','yyyymmdd'));
insert into 宿泊者 values('Ken',to_date('19991201','yyyymmdd'),to_date('19991225','yyyymmdd'));

create table 行事(
行事名   char(6),
StartDay Date,
EndDay   Date);

insert into 行事 values('元旦'  ,to_date('19990101','yyyymmdd'),to_date('19990101','yyyymmdd'));
insert into 行事 values('正月'  ,to_date('19990101','yyyymmdd'),to_date('19990103','yyyymmdd'));
insert into 行事 values('七夕'  ,to_date('19990707','yyyymmdd'),to_date('19990707','yyyymmdd'));
insert into 行事 values('大晦日',to_date('19991231','yyyymmdd'),to_date('19991231','yyyymmdd'));
commit;


SQL

--■■■notを使う方法■■■
select a.Name,b.行事名
from 宿泊者 a,行事 b
where not ((a.CheckOut < b.StartDay) or (b.EndDay < a.CheckIn))
order by a.Name,b.StartDay,b.EndDay;

--■■■上のSQLをドモルガンの法則を使って変形■■■
select a.Name,b.行事名
from 宿泊者 a,行事 b
where b.StartDay <= a.CheckOut and a.CheckIn <= b.EndDay
order by a.Name,b.StartDay,b.EndDay;


解説

notを使う方法では、
行事が始まる前に、チェックアウトするか、
行事が終わってから、チェックインしたら、
行事の間に宿泊できなかったと判断してます。

10-226 OverLaps述語