使用先验值作为回填的每日状态

Daily status using prior value as backfill

这是输入 table (tbl_statuslog):

User_id isactive date
1 1 1 Feb 2021
2 1 1 Feb 2021
3 1 2 Feb 2021
2 0 5 Feb 2021
4 1 10 Feb 2021
4 0 10 Feb 2021
3 0 12 Feb 2021
create table tbl_statuslog
(
  [user_id] int,
  [isactive] bit,
  [date] datetime
);

insert into tbl_statuslog (user_id, isactive, date) values
(1, 1, ' 1 Feb 2021'),
(2, 1, ' 1 Feb 2021'),
(3, 1, ' 2 Feb 2021'),
(2, 0, ' 5 Feb 2021'),
(4, 1, '10 Feb 2021'),
(4, 0, '10 Feb 2021'),
(3, 0, '12 Feb 2021');

我想 return 输出,因为今天是 2 月 16 日:

User_id isactive date
1 1 1 Feb 2021
.
.
.
1 1 16 Feb 2021
2 1 1 Feb 2021
.
.
2 1 4 Feb 2021
2 0 5 Feb 2021
.
.
2 0 16 Feb 2021
3 1 2 Feb 2021
.
.
3 1 11 Feb 2021
3 0 12 Feb 2021
.
.
3 0 16 Feb 2021
4 0 10 Feb 2021
.
.
4 0 16 Feb 2021

我使用以下 SQL 来获取所有日期的列表。

    DECLARE @StartDateTime DATETIME
    DECLARE @EndDateTime DATETIME
    
    SET @StartDateTime = '2021-02-01'
    SET @EndDateTime = GETDATE();
    
    WITH DateRange(DateData) AS 
    (
        SELECT @StartDateTime as Date
        UNION ALL
        SELECT DATEADD(d,1,DateData)
        FROM DateRange 
        WHERE DateData < @EndDateTime
    )
    SELECT DateData
    FROM DateRange
    OPTION (MAXRECURSION 0)
    GO

现在我正在考虑将此 table 与 tbl_statuslog table 进行左连接。因此,无论 tbl_statuslog 中是否存在日期,我都有一个日期。

然后我想回填日期的 isactive 值和 user_id 基于以前的值。

我可以使用 window 函数示例 partition by user_id, order by date 来实现结果吗?

我在这里被屏蔽了,因为在评估日期和 useridisactive 值时,我如何才能访问前 1 天的值或前 2 天的值(等等on) 当前一天没有价值时?

这回答了问题的原始版本。

我建议使用递归,但只针对每一行:

with ts as (
      select ts.*,
             lead(date) over (partition by user_id order by date) as next_date
      from tbl_statuslog ts
     ),
     cte as (
      select user_id, date, isactive,
             coalesce(dateadd(day, -1, next_date), convert(date, getdate())) as end_date
      from ts
      union all
      select user_id, dateadd(day, 1, date), isactive, end_date
      from cte
      where date < end_date
     )
select user_id, date,  isactive
from cte;

Here 是一个 db<>fiddle.