#oracle #rank #oracle19c #ranking-functions #oracle-analytics
Вопрос:
Не могли бы вы, пожалуйста, предложить простой способ вычисления ранга по нескольким столбцам в Oracle 19c.
For instance - considering [ Mango | 1 | 1 ] group from the table
NAME DAY PROD S M P AMT1 AMT2 AMT3
----------------------------------------------------------
MANGO 1 1 -2.75 3 15 21.277 80 80
MANGO 1 1 -2.75 1.5 21 27.778 80 80
MANGO 1 1 -2.75 3 21 27.778 80 80
MANGO 1 1 -2.75 3 14 20 80 80
Expected output : 2nd row
Для каждой группы [ИМЯ, ДЕНЬ, РЕЗУЛЬТАТ] мне нужно определить строку, имеющую минимальное значение[abs(S)].
Если это возвращает несколько строк с одинаковыми значениями [NAME, DAY, PROD, S], то следующим столбцом, который следует рассмотреть, является строка с максимальным значением(AMT1).
Опять же, если более чем одна строка извлекается с одним и тем же [ИМЕНЕМ, ДНЕМ, РЕЗУЛЬТАТОМ, S, AMT1], следующим фактором, который следует учитывать, является min(M).
И, наконец, мин(Р).
В целом, для каждой группы должна быть возвращена одна строка [ИМЯ, ДЕНЬ, РЕЗУЛЬТАТ] с учетом порядка ранжирования строк как min(abs(S)) -> max(AMT1) ->> min(M) ->>> min(P)>>>
Ожидаемые выходные данные для выборочных записей : Предоставленные списки SQL в DB_Fiddle
NAME DAY PROD S M P AMT1 AMT2 AMT3 final deciding factor
----------------------------------------------------------
APPLE 1 1 -2.5 3 21 27.778 80 80 ---> min(abs(S))
APPLE 8 0.5 -1.25 3 10 51.02 90 90 ---> max(AMT1)
MANGO 5 1 -1.75 3 14 24 83.333 83.333 ---> min(P)
MANGO 1 1 -2.75 1.5 21 27.778 80 80 ---> min(M)
Ответ №1:
Просто используйте ROW_NUMBER()
аналитическую функцию:
SELECT *
FROM (
SELECT t.*,
ROW_NUMBER() OVER (
PARTITION BY name, day, prod
ORDER BY ABS(s) ASC,
amt1 DESC,
m ASC,
p ASC
) AS rn
FROM test3 t
)
WHERE rn = 1;
Который для выборочных данных выводит:
Имя день подгонять S M P AMT1 AMT2 AMT3 rn Apple 1 1 -2.5 3 21 27.778 80 80 1 Apple 8 .5 -1.25 3 10 51.02 90 90 1 манго 1 1 -2.75 1.5 21 27.778 80 801 манго 5 1 -1.75 3 14 24 83.333 83.333 1
бд<>скрипка <>здесь
Комментарии:
1. Спасибо! @MT0 🙂