2016-03-09 72 views
1

我試圖從用戶分數條目列表中獲得總計用戶分數的排行榜。單個用戶在此表中可以有多個條目。PostgreSQL窗口函數「列必須出現在GROUP BY子句中」

我有如下表:

rewards 
======= 
user_id | amount 

我想補充了所有的amount值的給定用戶,然後對他們進行排名,在全球排行榜。下面是我試圖運行查詢:

SELECT user_id, SUM(amount) AS score, rank() OVER (PARTITION BY user_id) FROM rewards;

,我發現了以下錯誤:

ERROR: column "rewards.user_id" must appear in the GROUP BY clause or be used in an aggregate function 
LINE 1: SELECT user_id, SUM(amount) AS score, rank() OVER (PARTITION... 

是不是user_id已經在一個「聚合函數」,因爲我想對其進行分區? PostgreSQL的手冊顯示以下條目,我覺得是我的直接並聯,所以我不知道爲什麼我的不工作:

SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;

他們不是depname分組,怎麼讓他們的作品?

例如,對於如下的數據:

user_id | score 
=============== 
1 | 2 
1 | 3 
2 | 5 
3 | 1 

我期望以下輸出(I都作了 「扎」 用戶1之間和2):

user_id | SUM(score) | rank 
=========================== 
1 | 5 | 1 
2 | 5 | 1 
3 | 1 | 3 

所以用戶1總分爲5,並且排名第一,用戶2與分數爲5並且因此也是排名第一,並且用戶3排名第三,得分爲1.

+0

你想要什麼結果? –

+0

@JuanCarlosOropeza增加了一些細節。 – aardvarkk

回答

3

您需要GROUP BY USER_ID,因爲它沒有被聚合。然後你可以按照你想要的降序排列SUM(score);

SQL Fiddle Demo

SELECT user_id, SUM(score), RANK() OVER (ORDER BY SUM(score) DESC) 
FROM rewards 
GROUP BY user_id; 

user_id | sum | rank 
---------+-----+------ 
     1 | 5 | 1 
     2 | 5 | 1 
     3 | 1 | 3 
+0

這看起來是最簡單和最直接的方法。我想我需要提高我對「PARTITION BY」的確切含義的理解。謝謝你的幫助! – aardvarkk

+0

「PARTITION BY」對每一行都起着「GROUP BY」的作用。在這種情況下,您需要'GROUP BY',因爲您從4行開始並以3結尾。在問題情況下,如果您刪除了SUM(),那麼windows函數將返回所有4行 –

1

如果您有

SELECT user_id, SUM(amount) .... 
        ^^^ 
        agreagted function (not window function) 
    .... 
    FROM ..... 

你需要

GROUP BY user_id 
+0

如果我按user_id進行分組,他們全部排在第一位。分區有效地將它們分組,對嗎?我不明白這應該如何工作? – aardvarkk

+0

對不起,我只是回答什麼是錯的。我現在正在測試正確的方法:P –

2

有窗口函數與聚集函數之間的差。某些函數既可以用作窗口函數又可以用作聚合函數,這可能會導致混淆。窗口函數可以被查詢中的OVER子句識別。

然後,您的案例中的查詢將變爲,首先在user_id上進行聚合,然後在total_amount上執行窗口函數。

SELECT user_id, total_amount, RANK() OVER (ORDER BY total_amount DESC) FROM ( SELECT user_id, SUM(amount) total_amount FROM table GROUP BY user_id ) q ORDER BY total_amount DESC

相關問題