我有一个映射表如下:
FirstEntityID int
MappedTo int
BeginDate Date
EndDate Date
并且假设我在表格中有以下记录:
FirstEntityID MappedTo BeginDate EndDate
1 2 2012-09-01 2012-10-01
2 3 2012-09-01 2012-10-01
1 2 2012-10-02 2012-11-24
2 3 2012-11-01 2012-11-24
我需要一个脚本来获取此表并根据开始日期和结束日期合并记录以返回如下结果:
FirstEntityID MappedTo BeginDate EndDate
1 2 2012-09-01 2012-11-24
2 3 2012-09-01 2012-10-01
2 3 2012-11-01 2012-11-24
答案 0 :(得分:3)
使用CTE,我们首先找到开始日期:
; WITH StartD AS
( SELECT
FirstEntityID
, MappedTo
, BeginDate
, ROW_NUMBER() OVER( PARTITION BY FirstEntityID, MappedTo
ORDER BY BeginDate )
AS Rn
FROM
tableX AS t
WHERE
NOT EXISTS
( SELECT *
FROM tableX AS p
WHERE p.FirstEntityID = t.FirstEntityID
AND p.MappedTo = t.MappedTo
AND p.BeginDate < t.BeginDate
AND t.BeginDate <= DATEADD(day, 1, p.EndDate)
)
)
然后是结束日期:
, EndD AS
( SELECT
FirstEntityID
, MappedTo
, EndDate
, ROW_NUMBER() OVER( PARTITION BY FirstEntityID, MappedTo
ORDER BY EndDate )
AS Rn
FROM
tableX AS t
WHERE
NOT EXISTS
( SELECT *
FROM tableX AS p
WHERE p.FirstEntityID = t.FirstEntityID
AND p.MappedTo = t.MappedTo
AND DATEADD(day, -1, p.BeginDate) <= t.EndDate
AND t.EndDate < p.EndDate
)
)
和最终结果:
SELECT
s.FirstEntityID
, s.MappedTo
, s.BeginDate
, e.EndDate
FROM
StartD AS s
JOIN
EndD AS e
ON e.FirstEntityID = s.FirstEntityID
AND e.MappedTo = s.MappedTo
AND e.Rn = s.Rn ;
中进行测试
答案 1 :(得分:1)
经过测试,似乎有效
在有重复行的边缘情况下会失败 为此,需要采用像Ypercube这样的RowNumber方法 或者在表上添加约束以强制该行是唯一的。
-- first the overlaps
SELECT T1.FirstEntityId, T1.MappedTo, T1.BeginDate, Max(T2.EndDate) as [EndDate]
FROM tablex as T1
join tablex as T2
on T1.FirstEntityId = T2.FirstEntityId
and T1.MappedTo = T2.MappedTo
and T1.EndDate >= T2.BeginDate
and T1.EndDate < T2.EndDate
and T1.BeginDate <= T2.BeginDate
GROUP BY T1.FirstEntityId, T1.MappedTo, T1.BeginDate
union
-- add the non overlaps
SELECT T1.FirstEntityId, T1.MappedTo, T1.BeginDate, T1.EndDate
FROM tablex as T1
join tablex as T2
on T1.FirstEntityId = T2.FirstEntityId
and T1.MappedTo = T2.MappedTo
and ( T1.EndDate < T2.BeginDate or T1.BeginDate > T2.EndDate
or (T1.BeginDate < T2.BeginDate and T1.EndDate > T2.EndDate) )
order by FirstEntityId, MappedTo, BeginDate
答案 2 :(得分:0)
这可能有效:
SELECT FirstEntityId, MappedTo, Min(BeginDate), Max(EndDate)
FROM
T1
GROUP BY
FirstEntityId, MappedTo