Reputation: 935
I have a table of the form:
userid rank name
-------------------
1 4 raj
1 90 frank
1 100 neeta
1 123 liz
2 2 liz
2 20 neeta
2 23 frank
2 222 raj
I need to convert this into
userid min_rank next_min_rank
-------------------------------
1 raj frank
2 liz neeta
I have been searching the net for this issue for a long time but could not find a solution.
Could you please help?
Upvotes: 7
Views: 407
Reputation: 29051
Try this:
select a.userid , a.name minRank,
(select name from usertable where userid =a.userid and rank>a.rank
order by rank limit 1) nextMinRank
From (Select userid, name ,rank from usertable order by rank) as a
Group by userid, rank
Upvotes: 0
Reputation: 385
This did work for me with same data
SELECT N1.USERID AS USERID,N1.NAME AS MIN_RANK, N2.NAME AS NEXT_RANK
FROM (SELECT USERID,NAME FROM TABLE1 WHERE RANK IN(SELECT Min(Table1.rank) AS MinOfrank FROM Table1 GROUP BY Table1.UserID)) N1,
(SELECT USERID,NAME FROM TABLE1 WHERE RANK IN (SELECT Min(RANK) AS Expr1 FROM TABLE1 WHERE (TABLE1.rank) Not In (SELECT MIN(RANK) FROM TABLE1 GROUP BY USERID) GROUP BY USERID)) N2
WHERE
N1.USERID=N2.USERID;
Hope it helps!!
Upvotes: 1
Reputation: 14361
Not the most elegent one. But give it a try.
Query:
select b.userid, x.name1, b.name as name2
from ranks b
join
(
select a.userid, min(a.rank), a.name as name1
from ranks a
group by a.userid
) as x
on x.userid = b.userid
where (b.userid, b.rank, b.name) not in
(
select a.userid, min(a.rank), a.name
from ranks a
group by a.userid
)
group by b.userid
;
Results:
USERID NAME1 NAME2
1 raj frank
2 liz neeta
Upvotes: 2
Reputation: 49049
This query will select the minimun rank, and the next rank for every user:
select s.userid, s.min_rank, min(users.rank) as next_rank
from (
select userid, min(rank) as min_rank
from users
group by userid) s left join users
on users.userid = s.userid and s.min_rank<users.rank
group by s.userid
ant this will show the names:
select t.userid, t1.name, t2.name
from (
select s.userid, s.min_rank, min(users.rank) as next_rank
from (
select userid, min(rank) as min_rank
from users
group by userid) s left join users
on users.userid = s.userid and s.min_rank<users.rank
group by s.userid ) t
left join users t1 on t.userid=t1.userid and t.min_rank=t1.rank
left join users t2 on t.userid=t2.userid and t.next_rank=t2.rank
The result is:
1 raj frank
2 liz neeta
If there could be more than one user with the same rank, it depends on how you want to handle the situation, you might just add this:
group by t.userid
to show just one of them. Maybe you could also use GROUP_CONCAT(t1.name), GROUP_CONACT(t2.name)
on the select.
Upvotes: 2