将子表日期范围与父项合并

时间:2016-07-26 21:35:51

标签: sql sql-server

我过去曾问过类似的问题,想象一下已经有了答案,但我似乎无法弄清楚找到它的措辞。

我有一个带有日期范围的父表和一个子表,它可以在父表的日期范围内有多个日期范围。我需要将它们合并为一行,用于系列中的每个记录。一个例子应该更好地解释我正在尝试的内容:

表1(父母)

Date1    Date2    Person
1/1/16   7/1/16   A

和 表2(儿童)

Date1    Date2    Person
2/1/16   2/4/16   B
3/6/16   3/8/16   C
5/4/16   5/9/16   B

我想要一个像这样的合并表:

合并表

Date1    Date2    Person
1/1/16   2/1/16   A
2/1/16   2/4/16   B
2/4/16   3/6/16   A
3/6/16   3/8/16   C
3/8/16   5/4/16   A
5/4/16   5/9/16   B
5/9/16   7/1/16   A

必须有一个简单的方法来做到这一点?我对一个复杂的while循环很好,但我也对这个逻辑感到难过。

2 个答案:

答案 0 :(得分:1)

也许是这样的?

Declare @Table1 table (Date1 Date,Date2 Date, Person varchar(25))
Insert into @Table1 values 
('1/1/16','7/1/16','A')

Declare @Table2 table (Date1 Date,Date2 Date, Person varchar(25))
Insert into @Table2 values 
('2/1/16','2/4/16','B'),
('3/6/16','3/8/16','C'),
('5/4/16','5/9/16','B')

;with cteBase as (
    Select *
          ,Gap1 = Date2
          ,Gap2 = Lead(Date1,1,(Select max(Date2) from @Table1)) over (Order by Date1)
     From  @Table2 
)
Select Date1,Date2=(Select min(Date1) from @Table2),Person From @Table1
Union All
Select Date1,Date2,Person from cteBase
Union All
Select Date1=Gap1,Date2=Gap2,Person=B.Person
 From  cteBase A
 Join  @Table1 B on 1=1 
Order by Date1

返回

Date1       Date2       Person
2016-01-01  2016-02-01  A
2016-02-01  2016-02-04  B
2016-02-04  2016-03-06  A
2016-03-06  2016-03-08  C
2016-03-08  2016-05-04  A
2016-05-04  2016-05-09  B
2016-05-09  2016-07-01  A

答案 1 :(得分:1)

根据要求,这是一个考虑多个PK / FK的修改版本

Declare @Table1 table (PK int,Date1 Date,Date2 Date, Person varchar(25))
Insert into @Table1 values 
(1,'1/1/16','7/1/16','A'),
(2,'2/1/16','8/1/16','A')


Declare @Table2 table (FK int,Date1 Date,Date2 Date, Person varchar(25))
Insert into @Table2 values 
(1,'2/1/16','2/4/16','B'),
(1,'3/6/16','3/8/16','C'),
(1,'5/4/16','5/9/16','B'),
(2,'3/1/16','3/4/16','B'),
(2,'3/6/16','3/8/16','C'),
(2,'5/4/16','5/9/16','B')


;with cteBase as (
    Select *
          ,Gap1 = Date2
          ,Gap2 = Lead(Date1,1,(Select max(Date2) from @Table1 Where FK=PK)) over (Partition By FK Order by Date1)
     From  @Table2 
)
Select PK,Date1,Date2=(Select min(Date1) from @Table2 Where FK=PK),Person From @Table1
Union All
Select FK,Date1,Date2,Person from cteBase
Union All
Select FK,Date1=Gap1,Date2=Gap2,Person=B.Person
 From  cteBase A
 Join  @Table1 B on FK=PK
 Where Gap1<>Gap2
Order by PK,Date1

返回

PK  Date1       Date2       Person
1   2016-01-01  2016-02-01  A
1   2016-02-01  2016-02-04  B
1   2016-02-04  2016-03-06  A
1   2016-03-06  2016-03-08  C
1   2016-03-08  2016-05-04  A
1   2016-05-04  2016-05-09  B
1   2016-05-09  2016-07-01  A
2   2016-02-01  2016-03-01  A
2   2016-03-01  2016-03-04  B
2   2016-03-04  2016-03-06  A
2   2016-03-06  2016-03-08  C
2   2016-03-08  2016-05-04  A
2   2016-05-04  2016-05-09  B
2   2016-05-09  2016-08-01  A