我使用的是 SQL Server 2017。我有一个表 Requests,为了简单起见,只有一列 RequestDate。例如,
RquestDate
4/11
4/12
4/13
4/16
4/18
我需要考虑前瞻天数,按 RequestDate 分组。如果前瞻日为 0,则结果应与原始表相同。
如果前瞻日为 1,则表示当我查看 4/11 时,我需要检查 4/12 是否存在,如果存在,则将 4/12 分组为 4/11。 结果是:
4/11 --it groups 4/12
4/13
4/16
4/18
如果前瞻日为 2,则在查看 4/11 时,会将 4/12、4/13 分组到其中。 结果是:
4/11 -- group 4/12 and 4/13.
4/16 -- group 4/18
所以这个问题不同于典型的间隙和岛屿问题。因为当分组日期时,那里可能存在差距,例如,当展望前一天是 2、4/16 组 4/17 和 4/18 时。
我尝试了一些方法,但找不到合适的解决方案。
答案 0 :(得分:1)
递归公用表表达式可以工作。
min()
函数选择开始请求日期。第 1 步和第 2 步构成递归锚点/起始行。
r.RequestDate > c.RequestDate
) 并且没有其他行
在它之前遵循相同的标准 (not exists ... r2.RequestDate < r.RequestDate
)。then c.RequestGroupDate
),否则在当前请求日期 (else r.RequestDate
}).第 3 步和第 4 步构成了 CTE 的递归部分。
group by r.RequestGroupDate
子句将结果输出缩减为不同的值。示例数据
create table Requests
(
RequestDate date
);
insert into Requests (RequestDate) values
('2021-04-11'),
('2021-04-12'),
('2021-04-13'),
('2021-04-16'),
('2021-04-18');
解决方案
declare @lookAhead int = 1; -- look ahead days parameter
with rcte as
(
select min(r.RequestDate) as RequestDate,
min(r.RequestDate) as RequestGroupDate
from Requests r
union all
select r.RequestDate,
case
when datediff(day, c.RequestGroupDate, r.RequestDate) <= @lookAhead
then c.RequestGroupDate
else r.RequestDate
end
from rcte c
join Requests r
on r.RequestDate > c.RequestDate
where not exists ( select 'x'
from Requests r2
where r2.RequestDate > c.RequestDate
and r2.RequestDate < r.RequestDate )
)
select r.RequestGroupDate
from rcte r
group by r.RequestGroupDate;
结果
对于@lookAhead = 1
:
RequestGroupDate
----------------
2021-04-11
2021-04-13
2021-04-16
2021-04-18
对于@lookahead = 2
:
RequestGroupDate
----------------
2021-04-11
2021-04-16
Fiddle 查看实际情况。