PostgreSQL窗口函数"列必须出现在GROUP BY子句中#34;

时间:2016-03-09 21:04:45

标签: postgresql

我试图从用户评分条目列表中获取总计用户分数的排行榜。单个用户可以在此表中拥有多个条目。

我有下表:

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...

Isn' t 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

我希望以下输出(我在用户1和2之间做了#34; tie")

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

因此,用户1的总分为5,排名为#1,用户2的得分为5,因此排名为#1,用户3的排名为#3,得分为1。

3 个答案:

答案 0 :(得分:4)

您需要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

答案 1 :(得分: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

答案 2 :(得分:1)

如果你有

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

你需要

    GROUP BY user_id