我有一个包含一堆数字范围的表,如:
ID START END
1 1200 1500
2 1450 1700
3 1800 2100
4 2500 3000
5 2900 3300
我希望能够做的只是选择此组中的非重叠范围(例如, 1,3和4 ,或 1,3和5 < /强>)。另外,我必须能够指定一个额外的填充&#39;价值(如休息)可以变化。因此,例如,在选择ID = 1之后,我可能希望将400添加到结束值(从1500到1900),因此如果ID = 1是所选范围集的一部分,则ID = 3也不可用。
我已经看过不少于7到9个帖子了,他们看起来都非常接近我需要的,但不是那么的。我找到了一个可以找到重叠的:
SELECT *
FROM TEMP_Times a
JOIN TEMP_Times b on a.TimeStart <= b.TimeEnd
and a.TimeEnd >= b.TimeStart
and a.TimeID <> b.TimeID;
但是我没有把它转换成我需要的东西。如果需要递归那么好;最多我一次要抓10-12条记录。
答案 0 :(得分:1)
我认为NOT EXISTS
可以简化您的查询:
SELECT *
FROM @Test a
WHERE NOT EXISTS(
SELECT 1
FROM @Test b
WHERE a.TimeStart <= b.TimeEnd AND a.TimeEnd >= b.TimeStart
AND a.TimeStart >= b.TimeStart
AND a.TimeID <> b.TimeID
)
基于窗口函数的解决方案:
WITH cte AS(
SELECT *,
MaxEnd = MAX(TimeEnd) OVER (ORDER BY TimeStart ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
FROM @Test
)
SELECT *
FROM cte
WHERE MaxEnd IS NULL OR TimeStart > MaxEnd