0

これは次のような質問です: TSQL は datetime 範囲から重複する期間を取得しますが、結果の要求は異なります。

これはテーブルです:

create table period (
    id int,
    starttime datetime,
    endtime datetime,
    type varchar(64)
  );

insert into period values (1,'2013-04-07 8:00','2013-04-07 13:00','Work');
insert into period values (2,'2013-04-07 14:00','2013-04-07 17:00','Work');
insert into period values (3,'2013-04-08 8:00','2013-04-08 13:00','Work');
insert into period values (4,'2013-04-08 14:00','2013-04-08 17:00','Work');
insert into period values (5,'2013-04-07 10:00','2013-04-07 11:00','Holyday'); /* 1h overlapping with 1*/
insert into period values (6,'2013-04-08 10:00','2013-04-08 20:00','Transfer'); /* 6h overlapping with 3 and 4*/
insert into period values (7,'2013-04-08 11:00','2013-04-08 12:00','Test');  /* 1h overlapping with 3 and 6*/

重複しない一意の日時範囲テーブルが必要です。

前の例では、結果は次のようになります。

'2013-04-07 08:00','2013-04-07 13:00'
'2013-04-07 14:00','2013-04-07 17:00'
'2013-04-08 08:00','2013-04-08 20:00'

次のような時間の断片化が可能であれば、それほど重要ではありません。

'2013-04-08 08:00','2013-04-08 13:00'
'2013-04-08 12:00','2013-04-08 20:00'

- 編集 -

もう一つの例:

create table period (
    id int,
    starttime datetime,
    endtime datetime,
    type varchar(64)
  );

insert into period values (1,'2013-06-13 8:30','2013-06-13 12:30','');
insert into period values (2,'2013-06-13 8:38','2013-06-13 12:38','');
insert into period values (3,'2013-06-13 13:18','2013-06-13 17:45','');
insert into period values (4,'2013-06-13 13:30','2013-06-13 17:30','');
insert into period values (5,'2013-06-13 20:00','2013-06-13 23:59','');

これは返されるはずです:

2013-06-13 08:30 - 2013-06-13 12:38

2013-06-13 13:18 - 2013-06-13 17:45

2013-06-13 20:00 - 2013-06-13 23:59

4

2 に答える 2

2

しかし、重複していないピリオドは 1 つだけですか、それとも質問を間違って理解していましたか?

select * 
from period t
where id in (
select t1.id
from period t1 
join period t2 on t1.id <> t2.id
where t2.endtime <= t1.starttime or t2.starttime >= t1.endtime
group by t1.id
having count(*) + 1 = (select count(*) from period)
) 

結果:

'2013-04-07 14:00','2013-04-07 17:00'

更新:わかりましたので、重複する範囲をマージします。これを試して:

select starttime, endtime 
from period 
where id in (
select t1.id
from period t1 
join period t2 on t1.id <> t2.id
where t2.endtime < t1.starttime or t2.starttime > t1.endtime
group by t1.id
having count(*) + 1 = (select count(*) from period)
) 

union all

select min(start), max(fin) from (
select 
case when t2.starttime < t1.starttime then t2.starttime else t1.starttime end as start,
case when t2.endtime < t1.endtime then t1.endtime else t2.endtime end as fin
from period t1 
join period t2 on t1.id < t2.id
where t2.endtime >= t1.starttime and t2.starttime <= t1.endtime) overlaps
group by datepart(dd, start), datepart(dd, fin)
于 2013-04-16T09:14:26.600 に答える