【问题标题】:SQL status changes with start and end datesSQL 状态随开始日期和结束日期而变化
【发布时间】:2021-11-25 10:50:17
【问题描述】:

这是 2021 年 9 月 1 日至 2021 年 9 月 10 日期间用户状态的表格。 1 表示“活跃”。 0 表示“已取消”。

date user status
9/1/2021 1 1
9/1/2021 2 0
9/1/2021 3 1
9/2/2021 1 1
9/2/2021 2 1
9/2/2021 3 1
9/3/2021 1 0
9/3/2021 2 1
9/3/2021 3 1
9/4/2021 1 0
9/4/2021 2 1
9/4/2021 3 1
9/5/2021 1 0
9/5/2021 2 1
9/5/2021 3 0
9/6/2021 1 1
9/6/2021 2 1
9/6/2021 3 0
9/7/2021 1 1
9/7/2021 2 1
9/7/2021 3 0
9/8/2021 1 0
9/8/2021 2 1
9/8/2021 3 1
9/9/2021 1 0
9/9/2021 2 1
9/9/2021 3 1
9/10/2021 1 1
9/10/2021 2 0
9/10/2021 3 1

我想获取在此期间每个用户的活动和取消时段的开始和结束日期。我知道这涉及到一个窗口函数,但我不知道该怎么做。这是我想要的输出:

user status start date end date
1 1 9/1/2021 9/2/2021
1 0 9/3/2021 9/5/2021
1 1 9/6/2021 9/7/2021
1 0 9/8/2021 9/9/2021
1 1 9/10/2021 9/10/2021
2 0 9/1/2021 9/1/2021
2 1 9/2/2021 9/9/2021
2 0 9/10/2021 9/10/2021
3 1 9/1/2021 9/4/2021
3 0 9/5/2021 9/7/2021
3 1 9/8/2021 9/10/2021

【问题讨论】:

  • 不会按开始日期订购,状态工作?

标签: sql aggregate-functions window-functions


【解决方案1】:

更新

这里是一个例子:fiddle

更新的查询,

;with cte as (
         SELECT *,Rank() OVER ( partition by usr,status order by dt )as rnk
        ,LAG(dt,1) OVER (partition by usr order by dt desc) as LAG
        ,Row_number() over (partition by usr order by dt asc) as rnum
        ,count(*) over (partition by usr,status) as cnt
FROM TABLE1

     )
Select usr,status,dt as start_date,LAG as End_date  from cte 

【讨论】:

  • 嗯,当用户在取消后再次变得活跃时,这似乎没有捕捉到。如果用户活动或取消仅一天,它也不会返回正确的结束日期。
  • @bbk611 我更新了答案。我想,现在运行,你是如何描述它的。
  • 那也行不通。在您的示例表中,每个用户的状态,无论是活动还是取消,都只占用一行。在我提供的表格中,每个用户有时会在超过一天的时间内处于活跃或取消状态。所以他们的状态有时会占据不止一排。
【解决方案2】:

我想通了。

关键组件在当前状态不等于先前状态时进行过滤。这表示用户状态更改的日期。

当您过滤这些行时,您只需使用 LEAD() 窗口函数并减去 1 天即可获得该状态的结束日期。

with win as
(
select
  usr
  , dt
  , lag(status) over (partition by usr order by dt) as prev_status
  , status
from subs
)
select
  usr
  , status
  , dt as start_date 
  , coalesce(lead(dt) over (partition by usr order by dt) - interval '1 day', (select max(dt) from win)) as end_date
from win
where
  status <> prev_status
  or prev_status is null

【讨论】:

    猜你喜欢
    • 2022-12-01
    • 2020-04-30
    • 2012-08-19
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多