SQL不使用子查询实现分组后取每组第一条记录的方案问询
实现分组取每组第一条的无嵌套简化方案
可以不用嵌套子查询实现该需求,不同SQL方言都有对应的原生语法,无需冗余的子查询别名、也不会产生冗余字段:
- PostgreSQL、SQLite、ClickHouse 适用
DISTINCT ON语法
这是当前最简洁的实现方式,直接通过DISTINCT ON指定分组字段,配合ORDER BY决定每组取哪条记录:
SELECT DISTINCT ON (分组字段) * FROM whatever ORDER BY 分组字段, 排序字段 ASC -- 按需求调整排序规则,ASC取每组排序最靠前的,DESC取最靠后的
- MySQL 8.0+、Oracle、SQL Server、Snowflake 适用
QUALIFY子句QUALIFY是专门用于过滤窗口函数计算结果的语法,完全符合你理想中的书写逻辑,不需要任何嵌套:
SELECT * FROM whatever QUALIFY ROW_NUMBER() OVER (PARTITION BY 分组字段 ORDER BY 排序字段) = 1
- 低版本MySQL(5.x)等不支持以上语法的场景
可以用关联子查询实现,不需要手动罗列所有查询列,也没有额外冗余字段:
SELECT * FROM whatever t1 WHERE 排序字段 = ( SELECT MIN(排序字段) -- 需要取每组最大值时替换为MAX FROM whatever t2 WHERE t2.分组字段 = t1.分组字段 )
以上所有写法和你原本嵌套ROW_NUMBER的写法逻辑完全等价,性能基本一致,无需额外处理冗余字段。
注:如果存在多条记录分组字段、排序字段完全相同的情况,以上写法返回的结果和原
ROW_NUMBER写法逻辑一致,若需要保证结果确定性可以额外增加排序维度。
内容的提问来源于stack exchange,提问作者Darren Oakey
相关产品推荐
相关产品推荐

