在Redshift上使用start_date和end_date累计打开订阅

在Redshift上使用start_date和end_date累计打开订阅

问题描述:

我正在尝试编写一个查询,该数据将允许我在Redshift中每天统计活动订阅的数量。在Redshift上使用start_date和end_date累计打开订阅

我有如下表:

sub_id | start_date | end_date 
    --------------------------------------- 
    20001 | 2017-09-01 | NULL 
    20002 | 2017-08-01 | 2017-08-29 
    20003 | 2016-01-01 | 2017-04-25 
    20004 | 2016-07-01 | 2017-09-03 

我希望能状态时,两个日期许多订阅如何积极之间的每个日期,使得:

 date | active_subs 
    ------------------------ 
    2016-06-30 | 1 
    2016-07-01 | 2 
    ...  | 
    2017-04-24 | 2 
    2017-04-25 | 1 
    ...  | 
    2017-07-31 | 1 
    2017-08-01 | 2 
    ...  | 
    2017-08-28 | 2 
    2017-08-29 | 1 
    2017-08-30 | 1 
    2017-08-31 | 1 
    2017-09-01 | 2 
    2017-09-02 | 2 
    2017-09-03 | 1 

我有一个查询可以从中查询每天一行,日期的表名和相关列为date.ref_date(使用YYYY-MM-DD格式)

我写这个查询使用窗口函数还是有更好的方法?

感谢

如果我理解正确的话,你并不需要,也不窗口功能,连接(除了日期表)或累计计数。你可以这样做:

SELECT t.date, 
     COUNT(s.sub_id) as active_subs 
FROM dateTable t 
LEFT JOIN YourTable s 
ON(t.dateCol between s.start_date 
       AND COALESCE(s.end_date,<Put A late date here>)) 
GROUP BY t.date 
+0

当然,当别人把它写出来这么简单时,它就显而易见了。我试图让它复杂化。谢谢@sagi! – Ozmoges

+0

@Ozmoges。 。 。我建议你尝试使用窗口函数的解决方案。它应该在Redshift上有更好的表现。 –

+0

@GordonLinoff你对表演是否正确(不确定会有什么重大区别),但这个查询的维护会更困难..新的程序员经常对窗口函数感到困惑。 – sagi

我会做这样的:

with cte as (
     select start_date as dte, 1 as inc 
     from t 
     union all 
     select coalesce(end_date, current_date), -1 as inc 
     from t 
    ) 
select dte, 
     sum(sum(inc)) over (order by dte) 
from cte 
group by dte 
order by dte; 

有可能是关闭的情况的一个错误,这取决于你是否指望给出的日期或第二天停止。

+0

Redshift不支持递归CTE,即使它这样做对于这样一个简单的查询来说是一种矫枉过正。加入条件中的“BETWEEN”类似于其他答案,非常简单并且在此处运行良好 – AlexYes

+0

对于此CTE没有任何递归。这是解决此问题的最佳解决方案。 –

+0

是的,你是对的,它不是递归的,但我会争辩说,加入更清洁 – AlexYes