2017-04-25 61 views
0

我有與感興趣3個字段的表T: d(日期),PID(INT),和評分(數字)前N個值在窗框

我試圖計算第四字段是每個玩家的前N(3或5)分數的平均值。

我嘗試以下加入一個子查詢,但它不生產我在尋找的結果:

SELECT t.d, t.pid, t.score, sq.highscores 
FROM t, (SELECT *, avg(score) as highscores FROM 
    (SELECT *, row_number() OVER w AS rnum 
    FROM t AS t2 
    WINDOW w AS (PARTITION BY pid ORDER BY score DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)) isq 
    WHERE rnum <= 3) sq 
WHERE t.d = sq.d AND t.pid = sq.pid 

任何建議,將不勝感激!我是一個業餘愛好者程序員,這比查詢更復雜。

+0

如果您提供了一些示例值,那麼它會更有幫助。 –

回答

1

您不能在相同(內部)查詢中選擇*avg(score)10。即應該爲每個平均值選擇哪些非彙總值? PostgreSQL不會決定這個,而不是你。

在最裏面的查詢中,因爲PARTITION BY pid,您應該在聚合子查詢中使用GROUP BY pid。這樣,你可以SELECT pid, avg(score) as highscores

SELECT pid, avg(score) as highscores 
FROM  (SELECT *, row_number() OVER w AS rnum 
      FROM t AS t2 
      WINDOW w AS (PARTITION BY pid ORDER BY score DESC)) isq 
WHERE rnum <= 3 
GROUP BY pid 

ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING使得對row_number()沒有什麼區別。

但如果前N個部分是固定的(和N將在您的實際使用情況太少),就可以解決這個問題沒有那麼多子查詢(用nth_value()窗功能):

SELECT d, pid, score, 
     (coalesce(nth_value(score, 1) OVER w, 0) + 
     coalesce(nth_value(score, 2) OVER w, 0) + 
     coalesce(nth_value(score, 3) OVER w, 0))/
     ((nth_value(score, 1) OVER w IS NOT NULL)::int + 
     (nth_value(score, 2) OVER w IS NOT NULL)::int + 
     (nth_value(score, 3) OVER w IS NOT NULL)::int) highscores 
FROM t 
WINDOW w AS (PARTITION BY pid ORDER BY score DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 

http://rextester.com/GUUPO5148