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

SQL如何基于另一列条件筛选分组后某列取最小值的行

SQL按分组筛选指定列最小值对应行的实现方案

需求规则

根据给出的表结构和查询要求,核心规则如下:

  • 基础分组维度为PersonID、ConsultantID
  • 每组内优先取EpisodeNumber最小的整行数据
  • 同一PersonID下存在不同Diagnosis需单独区分统计

推荐解法:窗口函数法

支持MySQL 8.0+、PostgreSQL、SQL Server、Oracle等所有支持窗口函数的现代数据库,写法简洁性能稳定:

WITH ranked_data AS (
    SELECT
        *,
        ROW_NUMBER() OVER (
            PARTITION BY PersonID, ConsultantID, Diagnosis
            ORDER BY CAST(EpisodeNumber AS UNSIGNED) ASC
        ) AS rank_num
    FROM Persons
)
SELECT PersonID, Diagnosis, ConsultantID, EpisodeNumber
FROM ranked_data
WHERE rank_num = 1;

注意点说明

  • 由于示例表中EpisodeNumber定义为varchar类型,排序时通过CAST转为数值类型,避免字符串排序出现'10' < '2'的逻辑异常,如果你的实际表中该字段为数值类型可直接省略转换步骤
  • PARTITION BY后增加Diagnosis字段,实现同一用户、同一医生下不同诊断的单独分组,符合区分不同诊断的需求
  • 如果同一分组内存在多条EpisodeNumber相同的最小值行,希望全部返回时,可将ROW_NUMBER()替换为RANK()函数

低版本数据库兼容解法

如果使用不支持窗口函数的低版本数据库(如MySQL 5.x),可使用子查询关联的方式实现:

SELECT p.*
FROM Persons p
INNER JOIN (
    SELECT
        PersonID,
        ConsultantID,
        Diagnosis,
        MIN(CAST(EpisodeNumber AS UNSIGNED)) AS min_episode
    FROM Persons
    GROUP BY PersonID, ConsultantID, Diagnosis
) t ON p.PersonID = t.PersonID
    AND p.ConsultantID = t.ConsultantID
    AND p.Diagnosis = t.Diagnosis
    AND CAST(p.EpisodeNumber AS UNSIGNED) = t.min_episode;

执行结果

两种方法执行后得到的结果与预期一致,最终返回数据如下:

PersonIDDiagnosisConsultantIDEpisodeNumber
1Headache0011
1Stomachache0021
2Headache0031
3Hand0041
3Headache0031

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 06:00:00