You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle 19C中基于多列优先级规则的分组单行筛选方法咨询

Oracle 19C: 分组后按多优先级规则筛选单行的简便实现

在Oracle 19C里处理这种分组后按多规则筛选唯一行的需求,最省心的方法就是用窗口函数ROW_NUMBER()搭配自定义排序逻辑,不用写一堆嵌套子查询,代码简洁还容易维护。咱们直接结合你的需求和示例数据来拆解:

核心思路

利用ROW_NUMBER()窗口函数,针对[NAME, DAY, PROD]分组,然后按照你指定的优先级给每组内的行排序,最后只取每组中排名为1的行即可。排序规则严格对应你的要求:

  • 第一优先级:按ABS(S)升序(绝对值最小的行排最前)
  • 第二优先级:按AMT1降序(数值最大的行排最前)
  • 第三优先级:按M升序(数值最小的行排最前)
  • 第四优先级:按P升序(数值最小的行排最前)

完整SQL代码

SELECT t.NAME, t.DAY, t.PROD, t.S, t.M, t.P, t.AMT1, t.AMT2, t.AMT3
FROM (
    SELECT 
        *,
        ROW_NUMBER() OVER (
            PARTITION BY NAME, DAY, PROD
            ORDER BY ABS(S) ASC, AMT1 DESC, M ASC, P ASC
        ) AS rn
    FROM your_table_name
) t
WHERE t.rn = 1;

代码解释

  1. PARTITION BY子句:指定分组字段NAME, DAY, PROD,窗口函数会在每个分组内独立计算排名。
  2. ORDER BY子句:完全匹配你的优先级规则:
    • ABS(S) ASC:先找绝对值最小的S
    • AMT1 DESC:S绝对值相同时,取AMT1最大的
    • M ASC:前两个条件都相同时,取M最小的
    • P ASC:最后如果还有重复,取P最小的
  3. 外层筛选:只保留每组中rn=1的行,也就是每组按规则筛选出来的唯一行。

示例验证

拿你给出的MANGO分组示例数据来说:

NAMEDAYPRODSMPAMT1AMT2AMT3
MANGO11-2.7531521.2778080
MANGO11-2.751.52127.7788080
MANGO11-2.7532127.7788080
MANGO11-2.75314208080

分组内所有行的ABS(S)都是2.75,所以进入第二优先级AMT1 DESC,此时第2、3行的AMT1最大(27.778);接着看第三优先级M ASC,第2行的M是1.5,比第3行的3小,所以第2行的rn=1,最终会被筛选出来,完全符合你的预期。

再看你补充的几个示例:

  • APPLE 1-1分组:所有行ABS(S)最小的是-2.5(绝对值2.5),直接被选中
  • APPLE 8-0.5分组:在ABS(S)相同的情况下,AMT1最大的51.02对应的行被选中
  • MANGO 5-1分组:前面条件都相同时,P最小的14对应的行被选中

补充说明

如果你的需求里允许并列排名(比如多个行完全符合所有优先级规则时保留多行),可以把ROW_NUMBER()换成RANK()或者DENSE_RANK(),但根据你的描述,需要每组唯一一行,所以ROW_NUMBER()是最合适的。

内容的提问来源于stack exchange,提问作者Divya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 13:47:41