我正在处理一个查询,以获取用户的排名。我有两个表用于用户,另一个用于利润,我保存金额和与之相关的用户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
如果我的用户是Kobe Bryant,我需要得到Michael Jordan,Kobe Bryant和Phil Jackson的排名。
如果我的用户是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
答案 0 :(得分:1)
with s as (
select
users.id, users.name, total_profit,
rank() over(order by total_profit desc) as r
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
), u as (
select r from s where name = 'Kobe Bryant'
)
select distinct on (r) id, name, total_profit, r
from s
where
name = 'Kobe Bryant'
or r in (
(select r from u) - 1, (select r from u) + 1
)
order by r;
答案 1 :(得分:0)
with cte_profits as (
select
sum(p.amount) as total_profit, p.investor_id
from profits as p
group by p.investor_id
), cte_users_profits as (
select
u.id, u.name, p.toral_profit,
dense_rank() over(order by p.total_profit desc) as rnk,
row_number() over(partition by up.total_profit order by up.id) as rn
from users as u
inner join cte_profits as p on p.investor_id = u.id
)
select c2.*
from cte as c
left outer join cte as c2 on
c2.id = c.id or
c2.rnk = c.rnk + 1 and c2.rn = 1 or
c2.rnk = c.rnk - 1 and c2.rn = 1
where c.name = 'Kobe Bryant'
order by c2.rnk