【问题标题】:Can I put a window function inside a case statement to reference that case statement?我可以在 case 语句中放置一个窗口函数来引用该 case 语句吗?
【发布时间】:2018-07-01 18:13:09
【问题描述】:

我有一张包含订阅的表格。它有公司 id、订阅的开始和订阅的结束。我用窗口函数添加了排名。

这就是数据的样子 -

company_id  datestart   dateend rank
abc         1/1/17      1/5/17  1
aab         2/1/17      2/5/17  1
abb         1/15/17     1/30/17 1
abb         2/5/17      2/20/17 2
abb         5/1/17      5/15/17 3
abe         3/1/17      3/5/17  1
aad         2/1/17      3/1/17  1
aad         7/1/17      7/28/17 2
aad         8/15/17     8/17/17 3
aad         8/18/17     9/1/17  4

我想将它们分组。

我想要一个规则说-

如果 company_id 相同,并且下一次订阅在上次订阅后的 30 天内开始,则它们属于同一组。 如果 company_id 相同,并且下一次订阅在上次订阅的 30 天后开始,则将其设为 +1 期。

这就是我希望数据的样子 -

company_id  datestart   dateend rank    period
abc         1/1/17      1/5/17  1       1
aab         2/1/17      2/5/17  1       1
abb         1/15/17     1/30/17 1       1
abb         2/5/17      2/20/17 2       1
abb         5/1/17      5/15/17 3       2
abe         3/1/17      3/5/17  1       1
aad         2/1/17      3/1/17  1       1
aad         7/1/17      7/28/17 2       2
aad         8/15/17     8/17/17 3       2
aad         1/1/18      1/5/18  4       3

这是我尝试过的方法以及我遇到的问题 -

with subscriptions_cte as 
(SELECT company_id, datestart, dateend,
ROW_NUMBER() OVER (PARTITION BY company_id ORDER BY datestart) AS rank,
lag(datestart, 1) over (partition by company_id order by datestart asc) as prior_datestart,
lag(dateend, 1) over (partition by company_id order by datestart asc) as prior_dateend,
datediff(days, datestart, dateend) as subscription_length,
FROM subscriptions)

SELECT companyid, rank, datestart, dateend,
CASE WHEN rank = 1 then 1 
WHEN datediff(days, prior_dateend, datestart) < 30 THEN 
MAX(evaluation_period over (partition by companyid)
ELSE (MAX(evaluation_period) over (partition by companyid)) + 1  
END as evaluation_period
FROM subscriptions_cte

我被卡住了,因为我无法在评估周期的案例陈述中引用评估周期。我需要能够在下一个时期创造价值。让我知道是否可以包含更多信息。

杂项:这是使用 postgresql 进行的红移。

【问题讨论】:

    标签: sql case amazon-redshift common-table-expression window-functions


    【解决方案1】:

    我想你想要lag() 和一个累积和:

    select s.*,
           sum(case when prev_date_end >= date_start - interval '30 day' then 0 else 1 end ) over (partition by company_id order by rank) as period
    from (select s.*, lag(date_end) over (partition by company_id order by rank) as prev_date_end
          from subscriptions s
         ) s
    

    【讨论】:

      猜你喜欢
      • 2018-08-10
      • 1970-01-01
      • 2021-07-02
      • 2022-08-18
      • 2017-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-10
      相关资源
      最近更新 更多