SQL按ID分组筛选各ID对应最小Size值的实现方法
原查询语句失效原因
你当前写的语句逻辑是从T1中筛选ID存在于T1所有ID集合的记录,本质等价于SELECT ID, Size FROM T1,会返回表中全部原始数据,完全没有做「每个ID对应最小Size」的聚合过滤,自然达不到预期效果。
可实现需求的正确SQL方案
按照不同数据库版本和使用场景,有三类常用的实现方式:
1. 通用最简写法(全数据库兼容)
直接用分组聚合函数实现,是这类需求的首选方案,执行效率最高:
SELECT ID, MIN(Size) AS Size FROM T1 GROUP BY ID
- 逻辑说明:以ID为分组维度,对每组内的Size值取最小值,直接返回每个ID对应的最小Size结果,和预期输出完全匹配。
2. 窗口函数写法(适配主流现代数据库)
如果后续需要同步获取最小Size对应的整行其他字段,用窗口函数的写法扩展性更强,支持MySQL 8.0+、PostgreSQL、SQL Server等绝大多数当前在用的数据库版本:
SELECT ID, Size FROM ( SELECT ID, Size, -- 按ID分区,组内按Size升序排名,排名为1的就是当前ID的最小Size ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Size ASC) AS row_rank FROM T1 ) sorted_data WHERE row_rank = 1
3. 自关联写法(适配老旧无聚合优化的数据库版本)
如果使用的是不支持窗口函数的极老版本数据库(如MySQL 5.x及更早),可以用子查询算最小Size后做内关联:
SELECT main.ID, main.Size FROM T1 main INNER JOIN ( -- 子查询预先算出每个ID对应的最小Size值 SELECT ID, MIN(Size) AS min_size FROM T1 GROUP BY ID ) min_val ON main.ID = min_val.ID AND main.Size = min_val.min_size
注意:如果同一个ID下存在多个值等于最小Size的记录,该写法会返回所有匹配的记录,如需单条结果可在外层查询加
DISTINCT去重。
内容的提问来源于stack exchange,提问作者J D
相关产品推荐
相关产品推荐

