首页 > 解决方案 > 在 Oracle 19C 中的多个列上排名

问题描述

您能否建议一种简单的方法来计算 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

对于每个组 [NAME, DAY, PROD],我需要确定一个具有min[abs(S)]值的行。如果这返回具有相同值 [NAME, DAY, PROD, S] 的多行,则要考虑的下一列是具有max(AMT1)的行。同样,如果使用相同的 [NAME, DAY, PROD, S, AMT1] 获取多行,则要考虑的下一个因素是min(M)。最后,min(P)

总体而言,应为每个组 [NAME, DAY, PROD] 返回单行,考虑将行排序为min(abs(S)) -> max(AMT1) -> min(M) -> min(P)

示例记录的预期输出:在DB_Fiddle中提供的 SQL

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)

标签: oraclerankoracle19cranking-functionsoracle-analytics

解决方案


只需使用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;

其中,对于样本数据,输出:

姓名 产品 小号 AMT1 AMT2 AMT3 注册护士
苹果 1 1 -2.5 3 21 27.778 80 80 1
苹果 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

db<>在这里摆弄


推荐阅读