使用先验值作为回填的每日状态
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
来实现结果吗?
我在这里被屏蔽了,因为在评估日期和 userid
的 isactive
值时,我如何才能访问前 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.
这是输入 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
来实现结果吗?
我在这里被屏蔽了,因为在评估日期和 userid
的 isactive
值时,我如何才能访问前 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.