活动表:
create table #activity(id int, begin_date datetime, end_date datetime)
insert into #activity values(1, '1/1/2017', '1/31/2017')
insert into #activity values(1, '9/1/2017', '9/15/2017')
insert into #activity values(1, '4/1/2017', '4/15/2017')
insert into #activity values(1, '2/5/2017', '2/15/2017')
insert into #activity values(1, '8/1/2017', '8/31/2017')
Insert into #activity values(2, '11/1/2016', '11/15/2016')
现在输入日期是12/1/2016和id,想要在2016年12月1日之后的50天内完成所有活动。查询应返回活动,开始日期为2017年1月1日,2017年2月1日(因为这是在2017年1月31日的50天内)和4/1/17。
8/1/2017和9/1/2017的id 1不应该被选中8/1不是在50天的4/15和50天的周期被打破。
TIA
答案 0 :(得分:0)
OP说:
希望在2016年12月1日之后的50天内完成所有活动
实现该结果的一个可能的查询是
-- get all activities with a begin_date within 50 days of input_date
select *
from #activity as a
where @input_date <= a.begin_date and a.begin_date < dateadd(day, 50, @input_date)
然而,OP然后说:
查询应返回活动,开始日期为2017年1月1日1日,2017年2月5日(因为这是在2017年1月31日的50天内)和4/1/17。不应选择8/1的2017年8月1日和9月1日,而且在4/15和50天周期的50天内没有选择8/1。
这表明您希望查找从2016年12月1日开始的所有顺序活动,其中连续活动之间的差距小于50天。
一种可能的方法是使用lag函数。如何在此问题上使用滞后函数的示例是:
select
a.*
, lag(a.end_date, 1, @input_date) over (order by a.end_date) as previous_end
, datediff(day, lag(a.end_date, 1, @input_date) over (order by a.end_date), a.begin_date) as previous_end_to_this_begin
from #activity as a
where @input_date <= a.begin_date
order by a.begin_date
稍微简化会产生这个:
-- get all activities in a row where the gap between activities is less than 50
select * from #activity as a where @input_date <= a.begin_date and a.begin_date < (
select
min(a.begin_date) as first_begin_to_not_include
from
(
select
a.begin_date
, datediff(day, lag(a.end_date, 1, @input_date) over (order by a.end_date), a.begin_date) as previous_end_to_this_begin
from #activity as a
where @input_date <= a.begin_date
) as a
where a.previous_end_to_this_begin > 50
)
order by a.begin_date