通过考虑前瞻天数来分组日期

时间:2021-01-31 08:11:13

标签: sql-server group-by window-functions

我使用的是 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 时。

我尝试了一些方法,但找不到合适的解决方案。

1 个答案:

答案 0 :(得分:1)

递归公用表表达式可以工作。

  1. 使用 min() 函数选择开始请求日期。
  2. 使用与分组开始日期相同的日期。

第 1 步和第 2 步构成递归锚点/起始行。

  1. 递归地寻找下一个请求日期。此日期高于前一个日期 (r.RequestDate > c.RequestDate) 并且没有其他行 在它之前遵循相同的标准 (not exists ... r2.RequestDate < r.RequestDate)。
  2. 如果当前请求日期(从第 3 步开始)在前瞻间隔长度内,则保持分组开始日期 (then c.RequestGroupDate),否则在当前请求日期 (else r.RequestDate }).

第 3 步和第 4 步构成了 CTE 的递归部分。

  1. 递归之后的每个请求日期作为对应的请求分组日期。 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 查看实际情况。

相关问题