我想找到可覆盖的记录,并像下面SQL Server中的结果一样适当地确定它们的结束日期。如果可能的话,我也希望在结果中包含所有合并的id。
declare @t table(id int identity(1,1), name varchar(20), startdatetime datetime, enddatetime datetime);
insert into @t(name, startdatetime, enddatetime)
values
('ABC', '20200102 08:30', '20200102 09:30'),
('ABC', '20200102 08:31', '20200102 10:30'),
('ABC', '20200102 04:40', '20200102 05:30'),
('ABC', '20200102 04:55', '20200102 07:30'),
('XYZ', '20200102 04:40', '20200102 05:30'),
('XYZ', '20200102 04:40', '20200102 05:30'),
('XYZ', '20200102 05:20', '20200102 06:30'),
--
('x', '20200102 02:40', '20200102 03:30'),
('x', '20200102 03:30', '20200102 04:55'),
('x', '20200102 04:20', '20200102 05:35'),
('x', '20200102 05:35', '20200102 06:42'),
('x', '20200102 06:00', '20200102 08:15');
预期结果如
id name startdatetime enddatetime
1 ABC 20200102 08:30 20200102 08:30
2 ABC 20200102 08:31 20200102 10:30
3 ABC 20200102 04:40 20200102 04:54
4 ABC 20200102 04:55 20200102 07:30
我尝试了几个查询,它们都重叠了,但没有给出我需要的结果。
假设结束日期适当地意味着从重叠的开始日期时间中减去1分钟,并且没有记录可以完全在另一个记录中,这可能是代码的一个良好开端。
SELECT t.id,
t.name,
t.startdatetime,
CASE
WHEN t2.id IS NULL THEN t.enddatetime
ELSE DATEADD(MINUTE, -1, t2.startdatetime)
END AS adjustedEndDateTime
FROM @t AS t
LEFT JOIN @t AS t2 ON t.name = t2.name
AND t.startdatetime < t2.startdatetime
AND t.enddatetime > t2.startdatetime
如果你的记录可以完全重叠,那么你需要在t2.enddatetime周围添加一些额外的条件。
这是name="ABC"的结果
id name startdatetime adjustedEndDateTime
1 ABC 2020-01-02 08:30:00.000 2020-01-02 08:30:00.000
2 ABC 2020-01-02 08:31:00.000 2020-01-02 10:30:00.000
3 ABC 2020-01-02 04:40:00.000 2020-01-02 04:54:00.000
4 ABC 2020-01-02 04:55:00.000 2020-01-02 07:30:00.000