Второе самое высокое значение из таблицы Oracle DB

По таблицам:

USERS (user_name, email, balance)

Как создать запрос, возвращающий второй по величине баланс пользователя наиболее эффективным способом?

Мне удалось получить эту запись (но не эффективным способом) с помощью запроса:

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;

person e o    schedule 23.08.2016    source источник
comment
Вы можете получить некоторую идею из stackoverflow.com/questions/38990303/   -  person Jaydip Jadhav    schedule 23.08.2016
comment
Что вы хотите вернуть, если есть связи с наивысшим значением?   -  person Gordon Linoff    schedule 23.08.2016
comment
Ваш код в порядке, если у вас есть индекс users(Balance).   -  person Gordon Linoff    schedule 23.08.2016


Ответы (3)


Я бы использовал оконную функцию:

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

Я не думаю, что будет большая разница в производительности вашего запроса (особенно не с индексом balance), но, на мой взгляд, его легче читать и поддерживать.

person a_horse_with_no_name    schedule 23.08.2016
comment
предложение: вместо плотно_rank() лучше использовать row_number() - person Aishu; 23.08.2016
comment
@Aishu: но это не вернет нескольких пользователей с одинаковым балансом, который является вторым по величине. Он вернет только одного пользователя, даже если есть еще один с таким же (вторым по величине) балансом. - person a_horse_with_no_name; 23.08.2016

Попробуй это:

SELECT * 
FROM (SELECT *   
      FROM USERS   
      ORDER BY balance DESC  
      FETCH FIRST 2 ROWS ONLY
      ) 
ORDER BY balance DESC  
FETCH FIRST 1 ROWS ONLY
person Luthando Ntsekwa    schedule 23.08.2016
comment
Было бы неплохо сравнить эти 2 метода. Наверное, этот быстрее. - person vercelli; 23.08.2016
comment
Имейте в виду, что если ОП хочет дубликаты, он должен использовать WITH TIES - person vercelli; 23.08.2016

Это должно работать даже в случае, если более одного пользователя имеют одинаковый второй по величине баланс.

select * from USERS where balance IN
  (select max(balance) 
     from (select balance from USERS 
    where balance NOT IN (select max(balance) from USERS))
);
person NIRMAL K M    schedule 23.08.2016