используйте RANK или DENSE_RANK вместе с агрегатной функцией - PullRequest
0 голосов
/ 15 марта 2019

У меня есть таблица со следующими данными:

SCORE    ROW_ID   NAME
0.4      1011    ABC
0.95     1011    DEF
0.4      501     GHI
0.95     501     XYZ

В любой момент времени мне нужна только одна строка данных с максимальной оценкой, если есть более 1 записи, возьмите ту, которая имеет минимальный row_id.

Возможно ли достичь с помощью функции RANK или DENSE_RANK? Как насчет разбиения по?

MAX(score) keep(dense_rank first order by row_id)

Ответы [ 2 ]

0 голосов
/ 15 марта 2019

Вы ищете максимальный балл для одной строки, поэтому используйте row_number ():

select score, row_id, name
  from (select t.*, row_number() over (order by score desc, row_id) rn from t)
  where rn = 1

демо

Вы можете использовать rank и dense_rank в вашем примере, но они могут возвращать более одной строки, например, когда вы добавляете строку (0.95, 501, 'PQR') к своим данным.


keep dense_rank обычно используется, когда искомое значение отличается от критериев поиска, например, если мы ищем зарплату сотрудника, который работает дольше всего:

max(salary) keep (dense_rank first order by sysdate - hiredate desc)

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

max(salary) 
  keep (dense_rank first order by sysdate - hiredate desc) 
  over (partition by deptno)

Это то же самое, что и выше, но зарплата наиболее долго работающих сотрудников показана для каждого отдела отдельно. Вы даже можете использовать пустое значение over(), чтобы показать зарплату дольше всего работающего сотрудника в отдельном столбце, кроме других данных, таких как имя, зарплата, hire_date.

0 голосов
/ 15 марта 2019

Вам не нужно использовать dens_rank. Это поможет

SELECT * FROM (
  SELECT 
    SCORE,
    ROW_ID
    NAME 
  FROM T
  ORDER BY SCORE DESC, ROW_ID DESC
)
WHERE ROWNUM = 1;
...