在 Oracle 19C 中的多个列上排名
Rank on multiple columns in 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)] 值的行。
如果此 returns 多行具有相同的值 [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)
只需使用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;
其中,对于示例数据,输出:
NAME
DAY
PROD
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
MANGO
1
1
-2.75
1.5
21
27.778
80
801
MANGO
5
1
-1.75
3
14
24
83.333
83.333
1
db<>fiddle here
能否请您推荐一种在 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)] 值的行。 如果此 returns 多行具有相同的值 [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
中提供的 SQLNAME 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)
只需使用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;
其中,对于示例数据,输出:
NAME DAY PROD 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 MANGO 1 1 -2.75 1.5 21 27.778 80 801 MANGO 5 1 -1.75 3 14 24 83.333 83.333 1
db<>fiddle here