Postgres累积计数随着时间的推移

时间:2014-09-07 01:33:47

标签: postgresql timestamp cumulative-sum

我正在尝试在一个时间段内找到一个月内有效订阅的数量。

表:订阅 字段:

  • ID
  • “creationDate”
  • “deletionDate”

在以下情况下,订阅被视为在特定时间戳有效:

  1. deletionDate为空
  2. 特定时间戳介于creationDate和deletionDate
  3. 之间

    示例:

    • 订阅A有creationDate“2014-06-27 11:37:34.205 + 00”和deletionDate“2014-08-01 04:16:34.435 + 00”。订阅A在2014年6月,2014年7月和2014年8月被视为有效。
    • 订阅B有creationDate“2014-06-27 11:37:34.205 + 00”和deletionDate“2014-06-28 11:37:34.205 + 00”。订阅B仅在2014年6月有效。
    • 订阅C有creationDate“2014-06-27 11:37:34.205 + 00”,没有删除日期。订阅C在2014年6月之后被认为是有效的,直到当月。

    这就是我的尝试:

    select "Month", sum(sub) over (order by "Month" asc) as "Active subscriptions"
    from
    (select to_char(subscriptions."creationDate" at time zone '-7', 'YYYY-MM') as "Month", 
        count(distinct subscriptions.id) as sub
        from subscriptions
        where (to_char(subscriptions."deletionDate" at time zone '-7', 'YYYY-MM') is null 
            or to_char(subscriptions."deletionDate" at time zone '-7', 'YYYY-MM') >= to_char(subscriptions."creationDate" at time zone '-7', 'YYYY-MM') )
        group by "Month") as foo
    

    然而,问题在于它包括上个月的非活跃订阅数。为了说明我的意思,我的上述查询似乎包括2014年7月的订阅B(上例中)作为有效订阅。

    我不确定如何获取特定月份的“有效订阅”,以删除过去几个月内不再有效的订阅数。

    谢谢! :)

1 个答案:

答案 0 :(得分:5)

SELECT m, count(subscriptions.*) 
FROM subscriptions 
JOIN generate_series('2010-01-01'::date, now(), interval '1 mon') AS m
ON m >= subscriptions.creationDate AND 
       (subscriptions.deletionDate IS NULL OR m <= subscriptions.deletionDate)
/* You may get better indexed performance if you use a date 
   far in the future for current
  accounts, instead of NULL. Then you can use BETWEEN */
GROUP BY m ORDER BY m;