3

According to the tables:

USERS (user_name, email, balance)

How can I create a query that return the second highest user balance in the most efficient way ?

I successes to get this record (but not by the efficient way) with the query:

SELECT 
  * 
FROM  
  (SELECT 
    us.*,
    ROWNUM row_num
  FROM  
    (SELECT 
      u.*
    FROM
      users u
    ORDER BY
      u.BALANCE DESC) us
  WHERE
    ROWNUM < 3)
WHERE
  row_num > 1;
MT0
  • 143,790
  • 11
  • 59
  • 117
e o
  • 31
  • 2

3 Answers3

2

I would use a window function:

select *
from (
  select u.*, dense_rank() over (order by balance desc) as rnk
  from users u
) t
where rnk = 2;

I don't think there will be a big performance difference to your query (especially not with an index on balance) but in my opinion it's easier to read and maintain.

  • suggestion: instead of dense_rank() better to use row_number() – Aishu Aug 23 '16 at 15:59
  • @Aishu: but that wouldn't return multiple users with the same balance that is the second highest. It would only return a single user even if there is another one with the same (second highest) balance. –  Aug 23 '16 at 16:03
1

Try this:

SELECT * 
FROM (SELECT *   
      FROM USERS   
      ORDER BY balance DESC  
      FETCH FIRST 2 ROWS ONLY
      ) 
ORDER BY balance DESC  
FETCH FIRST 1 ROWS ONLY
Luthando Ntsekwa
  • 4,192
  • 6
  • 23
  • 52
0

This should work even in case of more than one user having same 2nd largest balance..

select * from USERS where balance IN
  (select max(balance) 
     from (select balance from USERS 
    where balance NOT IN (select max(balance) from USERS))
);
J. Chomel
  • 8,193
  • 15
  • 41
  • 69
NIRMAL K M
  • 17
  • 2