【发布时间】:2013-08-16 16:58:05
【问题描述】:
我现在正在处理一个查询,以获取我的用户排名。我有两张表,一张用于用户,另一张用于利润,我保存金额和与之相关的用户 ID。通过获得一个用户产生的总利润,我需要建立一个包含三个用户的排名,排名靠前的用户对我的用户,我的用户和排名靠后的用户对我的用户。例如:
id | name | total_profit | rank
-------+-----------------------------+--------------+------
10312 | John Doe | 7000.0 | 1
10329 | Michael Jordan | 5000.0 | 2
10333 | Kobe Bryant | 4000.0 | 3
10327 | Mike Bibby | 4000.0 | 3
10331 | Phil Jackson | 1000.0 | 4
如果我的用户是科比·布莱恩特,我需要获得迈克尔·乔丹、科比·布莱恩特和菲尔·杰克逊的排名。
如果我的用户是 Mike Bibby,我需要获得 Michale Jordan、Mike Bybby 和 Phil Jackson 的排名。
到目前为止,我有一个查询返回给我所有用户的完整排名,但我现在不知道什么是获得我想要的三个用户的好方法。我曾尝试用 ruby 来做到这一点,但我认为如果我在数据库中进行所有这些处理会更好。
SELECT users.id, users.name, total_profit, rank() OVER(ORDER BY total_profit DESC)
FROM users
INNER JOIN (SELECT sum(profits.amount) AS total_profit, investor_id
FROM profits GROUP BY profits.investor_id) profits ON profits.investor_id = users.id
ORDER BY total_profit DESC;
我正在使用 PostgresSQL 9.1.4
【问题讨论】:
-
在 Window Functions 方面做得更好的人可以回答,但我认为 LAG() 和 LEAD() 会得到你想要的。 postgresql.org/docs/9.1/static/functions-window.html
-
那么你想让科比在你的例子中排名第三还是第二?
-
Kobe bryant 的排名应该是 3,因为他与 Mike Bibby 并列,但在我的最终排名中,我不想显示并列,只想让用户排名更高和排名更低
-
@Eddie 很抱歉,您接受的答案不正确 - 请参阅 sqlfiddle.com/#!1/a2ff5/2
-
@Roman 更新为每个等级只有一个用户。
标签: sql postgresql postgresql-9.1 window-functions