这是一个关于提交缺少范围数据的问题。具体来说,我有一个结果集,其中每一行包含一个StartDate和EndDate值。假设我有:
Start End
1/15 1/20
1/12 3/15
我需要一个生成的查询将以下行添加到数据中:
1/21 2/11
大多数其他相关问题都是关于填补知识集(如日期列表)中的差距。在这种情况下,我只是在寻找丢失数据的开始/结束。
答案 0 :(得分:2)
假设您打算写1/21而不是2/21,这是一种方法:
with dates as
(
select '2016-01-15' as dtStart, '2016-01-20' as dtEnd union all
select '2016-02-12', '2016-03-15' union all
select '2016-03-21', '2016-04-11'
),
calcs as
(
select
dateadd(day, 1, dtEnd) as rangeStart,
(select dateadd(day, -1, min(dtStart))
from dates d2 where d2.dtStart > d.dtEnd) as rangeEnd
from dates d
)
select *
from calcs c
where c.rangeEnd >= c.rangeStart
表dates
只是三行样本日期。在calcs
表格中,rangeStart
列是每个dtEnd
之后的第二天。 rangeEnd
列会使用下一个dtStart
并减去一天。最后,最后一行将为null,因为在最后一个dtEnd之后现在缺少范围,所以我忽略了具有空rangeEnd
值的行。
编辑:如果您不熟悉我的代码中的with
语句,则为CTE。我在这里使用它作为一种快速方法来创建一个包含一些样本数据的表(日期)和一个存储计算的地方(计算)。
Edit2:由于您提到在评论中使用了联接,这是一种方法:
with dates as
(
select '2016-01-15' as dtStart, '2016-01-20' as dtEnd union all
select '2016-02-12', '2016-03-15' union all
select '2016-03-21', '2016-04-11'
),
calcs as
(
select
dateadd(day, 1, d1.dtEnd) as rangeStart,
dateadd(day, -1, min(d2.dtStart)) as rangeEnd
from dates d1
join dates d2 on d1.dtEnd < d2.dtStart
group by d1.dtEnd
)
select *
from calcs
where datediff(day, rangeStart, rangeEnd) >= 0
Edit3:更新了datediff不等式以包含一天的范围
答案 1 :(得分:0)
我建议创建一个日期表。这将使您的查询简单,您可以在其他查询中重用。以下是有关创建日期表的文章的链接。希望这会有所帮助。
答案 2 :(得分:0)
select * from
(select DISTINCT t1.[end] + 1 'start', t2.start - 1 'end'
from yourtable t1
CROSS JOIN
yourtable t2
WHERE
EXISTS(SELECT 0 FROM yourtable t3 WHERE t3.[end] < t2.[start])
AND
NOT EXISTS(SELECT 0 FROM yourtable t4 WHERE t4.start = t1.[end] + 1)
AND
NOT EXISTS(SELECT 0 FROM yourtable t5 WHERE T5.Start BETWEEN t1.[end] + 1 AND t2.start - 1 OR T5.[end] BETWEEN t1.[end] + 1 AND t2.start - 1)
AND
t1.[end] + 1 <= t2.start - 1
UNION
SELECT start,[end] from yourtable) dq
order by start
答案 3 :(得分:0)
Declare @Table table (Start Date,[End] Date)
Insert into @Table values
('2016-01-15','2016-01-20'),
('2016-02-12','2016-03-15')
;with cteBase as (
Select *,Gap=DateDiff(DD,Lag([End],1,Start) over (Order By Start),Start) From @Table
)
Select Start=DateAdd(DD,1+Gap*-1,Start),[End]=DateAdd(DD,-1,Start) from cteBase Where Gap<>0
返回
Start End
2016-01-21 2016-02-11
完整数据集
的可选项...
Union All
Select Start,[End] from cteBase
Order by Start