トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
7-5 同一日付を期間に含むレコード数
SQLパズル
期間テーブル
NO FromTime ToTime
-- ---------- ----------
1 2005-08-01 2005-08-03
2 2005-08-05 2005-08-10
3 2005-08-07 2005-08-15
4 2005-08-08 2005-08-13
5 2005-08-17 2005-08-25
期間テーブルのレコードで、
8/8を期間に含むレコード数は、3で、
8/15を期間に含むレコード数は、1となってます。
このテーブルに新たに期間データを登録する。
ただし、日付ごとの、同一日付を期間に含むレコード数が、3を超えてしまう場合は登録しない
データ作成スクリプト
create table 期間(
NO number(1),
FromTime date,
ToTime date);
insert into 期間 values(1,to_date('20050801','yyyymmdd'),to_date('20050803','yyyymmdd'));
insert into 期間 values(2,to_date('20050805','yyyymmdd'),to_date('20050810','yyyymmdd'));
insert into 期間 values(3,to_date('20050807','yyyymmdd'),to_date('20050815','yyyymmdd'));
insert into 期間 values(4,to_date('20050808','yyyymmdd'),to_date('20050813','yyyymmdd'));
insert into 期間 values(5,to_date('20050817','yyyymmdd'),to_date('20050825','yyyymmdd'));
commit;
SQL
--■■■FromTimeが8/8、ToTimeが8/10(insert不可)■■■
insert into 期間(NO,FromTime,ToTime)
select 6,to_date('20050808','yyyymmdd'),to_date('20050810','yyyymmdd') from dual
where
(select max(count(*))
from 期間 a,
(select to_date('20050808','yyyymmdd')+RowNum as 日付
from all_catalog
where to_date('20050808','yyyymmdd')+RowNum <= to_date('20050810','yyyymmdd')) b
where b.日付 between a.FromTime and a.ToTime
group by b.日付) < 3;
--■■■FromTimeが8/15、ToTimeが8/25(insert可)■■■
insert into 期間(NO,FromTime,ToTime)
select 6,to_date('20050815','yyyymmdd'),to_date('20050825','yyyymmdd') from dual
where
(select max(count(*))
from 期間 a,
(select to_date('20050815','yyyymmdd')+RowNum as 日付
from all_catalog
where to_date('20050815','yyyymmdd')+RowNum <= to_date('20050825','yyyymmdd')) b
where b.日付 between a.FromTime and a.ToTime
group by b.日付) < 3;
解説
サブクエリを使って、
FromTimeからToTimeまでの各日付を期間に含むレコード数をチェックしてます。
insert時にチェックするので、
ファントムリードやアンリピータブルリードが発生しづらくなります。
トランザクションの並列処理時に発生する問題
RowNum指定によるCountStopの資料