2017-06-14 71 views
0

我有一個事件數據庫,代表用戶註冊,降級和升級他們的計劃。它包含用戶密鑰,日期密鑰和計劃密鑰。要查找用戶當前的計劃,您可以搜索用戶密鑰的最新事件,然後查找與該計劃關聯的計劃,即使使用計劃密鑰。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

@LaurenzAlbe好的,謝謝,我添加了示例表 – JMoir

+0

在最內層的查詢中沒有'SELECT',並且如果可能的話,嘗試縮小內部查詢中的結果(WHERE ...) – verhie

回答

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()。性能通常要快一點。

+0

感謝您的回覆! g和t表從哪裏來? 感謝DISTINCT ON而不是ROW_NUMBER()! – JMoir

+0

@JMoir。 。 。表別名都混淆了。 't'應該是's','g'是'generate_series()'的結果。 –