Postgresql运行总结为每个日期的日期

时间:2017-06-14 10:01:12

标签: sql database postgresql

我有一个事件数据库,代表用户注册,降级和升级他们的计划。它包含用户密钥,日期密钥和计划密钥。要查找用户当前计划,您需要搜索用户密钥的最新事件,然后使用计划密钥查找与之关联的计划。

然后,为了得到mmr,您只需总结每个用户的计划价格。我有以下SQL来执行此操作;

SELECT SUM(pl_price)
FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY t.u_id ORDER BY t.d_iso DESC) rn
    FROM (
        subscription s INNER JOIN user u ON s.s_userkey = u.u_userkey
        INNER JOIN plan pl ON s.s_plankey = pl.pl_plankey
        INNER JOIN date d on s.s_datekey = d.d_datekey
    ) t
) t2
WHERE rn = 1

我现在想要做的是找出每个月的历史mmr。换句话说,它需要为每个月执行上面的sql查询,并忽略它所在月份之后的所有事件。

我该怎么做?我尝试的任何事情都没有接近工作......

编辑:示例表格 - 订阅

s_subkey|s_userkey|s_plankey|s_datekey
1       |2000     |23       |10
...

用户

u_userkey|u_id|u_name|...|
1        |33  |foo   |...|
...

计划

pl_plankey|pl_name|pl_price
1         |aplan  |10
...

日期

d_datekey|d_date    |d_iso    |d_yearmonth|...|
1        |10-03-2017|*isodate*|Jun2017    |...|
...

当前查询适用于获取当月的MMR,因此在6月份。我想要一张这样的桌子:

monthyear|mmr
Jan17    |1000000
Feb17    |1100000
Mar17    |1200000
...      |...

1 个答案:

答案 0 :(得分:0)

这是一种蛮力方法。它生成感兴趣的月份,然后使用此信息计算每个月的值:

SELECT mon, SUM(pl_price)
FROM (SELECT DISTINCT ON s.uid, g.mon) s.uid, g.mon, pl_price
      FROM generate_series('2017-01-01'::timestamp, '2017-06-01'::timestamp, interval '1 month') g(mon) CROSS JOIN
           subscription s INNER JOIN
           user u 
           ON s.s_userkey = u.u_userkey INNER JOIN
           plan pl
           ON s.s_plankey = pl.pl_plankey INNER JOIN
           date d 
           ON s.s_datekey = d.d_datekey
       WHERE d.date_key <= g.mon
       ORDER BY s.uid, g.mon, t.d_iso DESC
      ) s
GROUP BY mon
ORDER BY mon;

请注意,这使用DISTINCT ON而不是ROW_NUMBER()。性能通常会快一点。