我可以在case语句中放置一个窗口函数来引用该case语句吗?

时间:2018-01-23 01:52:51

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

我有一张订阅表。它具有公司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

我被卡住了,因为我无法在evaluation_period的case语句中引用evaluation_period。我需要能够在下一个时期创造价值。如果有更多我可以提供的信息,请告诉我。

其他:这是与postgresql进行红移的。

1 个答案:

答案 0 :(得分: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