Postgresql 研究生随时间累积计数

Postgresql 研究生随时间累积计数,postgresql,timestamp,cumulative-sum,Postgresql,Timestamp,Cumulative Sum,我正在尝试查找一个月内某个时间段内的活动订阅数 表:订阅 字段: 身份证 “肌酸盐” “删除日期” 在以下情况下,订阅在特定时间戳被视为活动: 删除日期为空 特定的时间戳介于creationDate和deletionDate之间 例如: 认购A的创建日期为“2014-06-27 11:37:34.205+00”,删除日期为“2014-08-01 04:16:34.435+00”。认购A在2014年6月、2014年7月和2014年8月被视为有效 订阅B的创建日期为“2014-06-27 11

我正在尝试查找一个月内某个时间段内的活动订阅数

表:订阅 字段:

  • 身份证
  • “肌酸盐”
  • “删除日期”
在以下情况下,订阅在特定时间戳被视为活动:

  • 删除日期为空
  • 特定的时间戳介于creationDate和deletionDate之间
  • 例如:

    • 认购A的创建日期为“2014-06-27 11:37:34.205+00”,删除日期为“2014-08-01 04:16:34.435+00”。认购A在2014年6月、2014年7月和2014年8月被视为有效
    • 订阅B的创建日期为“2014-06-27 11:37:34.205+00”,删除日期为“2014-06-28 11:37:34.205+00”。认购B仅在2014年6月有效
    • 认购C的创建日期为“2014-06-27 11:37:34.205+00”,没有删除日期。自2014年6月起至当月,认购C被视为有效
    这就是我所尝试的:

    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
    
    但是,问题是,它包括上个月的非活动订阅计数。为了说明我的意思,我上面的查询似乎包括订阅B(在上面的示例中)作为2014年7月的活动订阅

    我不知道如何获取特定月份的“活动订阅”,以删除前几个月不再活动的订阅计数

    谢谢!:)

    选择m,计数(订阅。*)
    来自订阅
    将generate_series('2010-01-01'::date,now(),interval'1 mon')连接为m
    在m>=subscriptions.creationDate和
    
    (subscriptions.deletionDate为NULL或m Date支持“infinity”,这很好地满足了要求。感谢您的帮助!
    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;