使用 RANK() 根据 Oracle 中的多个条件分配排名
Using RANK() to assign a rank based on multiple criteria in Oracle
我有一个 table 类似于:
Item
Class
Qty
Loc
Apple
Fruit1
1
N
Apple
Fruit1
1
NW
Apple
Fruit2
0
W
Apple
Fruit3
1
N
Orange
Fruit1
10
SE
Orange
Fruit2
1
SW
我正在尝试查询具有最低 Class
且每个 Item
具有最小 非零 Qty
的所有行。因此,如果相同的 Item
对于多个 类 具有相同的 Qty
,它将 select 最低的 Class
(Fruit1
< Fruit2
< Fruit3
< ...)。我试过使用类似的东西:
SELECT A.*,
RANK() OVER(
PARTITION BY ITEM, CLASS
ORDER BY QTY ASC, CLASS ASC) AS item_rank
FROM fruits.info
WHERE QTY <> 0
获得 select 的排名,但这是行不通的。排名结果应该是:
Item
Class
Qty
Loc
item_rank
Apple
Fruit1
1
N
1
Apple
Fruit1
1
NW
1
Apple
Fruit3
1
N
2
Orange
Fruit1
10
SE
2
Orange
Fruit2
1
SW
1
然后我会为 item_rank = 1
使用嵌套的 select:
SELECT B.* FROM (
SELECT A.*,
RANK() OVER(
PARTITION BY ITEM, CLASS
ORDER BY QTY ASC, CLASS ASC) AS item_rank
FROM fruits.info
) B
WHERE B.item_rank = 1
得到最终的结果,应该是:
Item
Class
Qty
Loc
item_rank
Apple
Fruit1
1
N
1
Apple
Fruit1
1
NW
1
Orange
Fruit2
1
SW
1
如何构建我的 RANK()
来实现这一点?有没有更高效的方法?
class
只能用于排序,不能用于分区。您想要每个 item
的排名,而不是每对 item
和 class
.
的排名
您尝试中的(易于修复的)错误是将 class
同时包含在 partition by
和 order by
中;如果你想一想,那永远没有意义:如果你按某物进行分区,那么按它进一步排序(在每个分区中,“它”是常量)是没有意义的。从 partition by
中删除 class
,你应该得到你需要的。
我有一个 table 类似于:
Item | Class | Qty | Loc |
---|---|---|---|
Apple | Fruit1 | 1 | N |
Apple | Fruit1 | 1 | NW |
Apple | Fruit2 | 0 | W |
Apple | Fruit3 | 1 | N |
Orange | Fruit1 | 10 | SE |
Orange | Fruit2 | 1 | SW |
我正在尝试查询具有最低 Class
且每个 Item
具有最小 非零 Qty
的所有行。因此,如果相同的 Item
对于多个 类 具有相同的 Qty
,它将 select 最低的 Class
(Fruit1
< Fruit2
< Fruit3
< ...)。我试过使用类似的东西:
SELECT A.*,
RANK() OVER(
PARTITION BY ITEM, CLASS
ORDER BY QTY ASC, CLASS ASC) AS item_rank
FROM fruits.info
WHERE QTY <> 0
获得 select 的排名,但这是行不通的。排名结果应该是:
Item | Class | Qty | Loc | item_rank |
---|---|---|---|---|
Apple | Fruit1 | 1 | N | 1 |
Apple | Fruit1 | 1 | NW | 1 |
Apple | Fruit3 | 1 | N | 2 |
Orange | Fruit1 | 10 | SE | 2 |
Orange | Fruit2 | 1 | SW | 1 |
然后我会为 item_rank = 1
使用嵌套的 select:
SELECT B.* FROM (
SELECT A.*,
RANK() OVER(
PARTITION BY ITEM, CLASS
ORDER BY QTY ASC, CLASS ASC) AS item_rank
FROM fruits.info
) B
WHERE B.item_rank = 1
得到最终的结果,应该是:
Item | Class | Qty | Loc | item_rank |
---|---|---|---|---|
Apple | Fruit1 | 1 | N | 1 |
Apple | Fruit1 | 1 | NW | 1 |
Orange | Fruit2 | 1 | SW | 1 |
如何构建我的 RANK()
来实现这一点?有没有更高效的方法?
class
只能用于排序,不能用于分区。您想要每个 item
的排名,而不是每对 item
和 class
.
您尝试中的(易于修复的)错误是将 class
同时包含在 partition by
和 order by
中;如果你想一想,那永远没有意义:如果你按某物进行分区,那么按它进一步排序(在每个分区中,“它”是常量)是没有意义的。从 partition by
中删除 class
,你应该得到你需要的。