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

SQL如何仅对指定百分比的行应用MIN() OVER窗口函数计算最小值

实现分组排除指定比例最低值后取窗口最小值的方案

你原查询直接用MIN() OVER()取的是分组全量数据的最小值,要实现排除组内最低X%行后再取最小值,可以通过窗口百分比排名函数做中间层计算,步骤和代码如下:

核心逻辑

  • 先按deptno + job分组,组内按sal升序计算每行的百分比排名,标记每行在组内薪资从低到高的累计位置占比
  • 计算最小值时,只统计百分比排名大于等于排除阈值的行,自动过滤掉前X%的最低薪资行
  • 最终结果仍然保留原表所有行,和你原查询的返回行结构一致

可直接运行的代码(以排除50%最低行为例)

兼容MySQL 8.0+、PostgreSQL、Oracle、SQL Server等所有支持标准窗口函数的数据库:

WITH ranked_emp AS (
    SELECT
        empno,
        ename,
        deptno,
        sal,
        job,
        -- 组内按薪资升序计算百分比排名,取值范围0~1
        PERCENT_RANK() OVER (PARTITION BY deptno, job ORDER BY sal ASC) AS sal_rank_pct
    FROM emp
)
SELECT
    empno,
    ename,
    deptno,
    sal,
    job,
    -- 阈值0.5对应排除前50%的最低薪资行,可按需调整数值
    MIN(CASE WHEN sal_rank_pct >= 0.5 THEN sal END)
      OVER (PARTITION BY deptno, job) AS min_sal_by_dept_and_job
FROM ranked_emp;

补充说明

  • 调整排除比例只需要修改判断条件里的阈值即可:比如要排除最低20%的薪资行,把0.5改成0.2就行
  • 按你给出的示例场景,组内两个薪资为1250的行百分比排名低于0.5,会被排除在计算范围外,最终统计1500、1600两个值的最小值,返回结果1500,完全匹配你的预期
  • 如果你的业务规则是按“薪资值的累计占比”而非“行数的累计占比”过滤,可以把PERCENT_RANK()替换成CUME_DIST(),两者计算逻辑略有差异,可根据实际边界需求选择:
    • PERCENT_RANK()计算规则:(当前行升序排名 - 1) / (组内总行数 - 1),组内薪资最低的行排名值固定为0
    • CUME_DIST()计算规则:小于等于当前薪资的行数 / 组内总行数,适合需要按薪资值分布做过滤的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:36:07