SQL中如何获取聚合列对应的关联列且避免重复遍历表?
关于SQL聚合查询中关联字段取值与高效查询的问题
问题1:select max(a), b from some_table中b的取值是否对应a最大值的行?
答案是不一定,甚至在严格SQL模式下这个查询会直接报错:
- 当数据库开启
ONLY_FULL_GROUP_BY模式(如MySQL默认开启、PostgreSQL等),由于b既不在GROUP BY子句中,也未被聚合函数包裹,查询会直接违反SQL标准报错。 - 若关闭该模式(如旧版MySQL),
b会返回表中随机一行的值,大概率不是a取最大值的那一行,结果完全不可控。
问题2:如何无需二次遍历表实现获取a最大值对应的b?
以下几种方法都可以避免两次全表扫描,效率更高:
方法1:使用窗口函数(推荐,通用型强)
适配大多数现代数据库(MySQL 8.0+、PostgreSQL、SQL Server等),仅需一次表遍历即可完成:
SELECT a, b FROM ( SELECT a, b, -- 按a降序排序,为每行分配序号 ROW_NUMBER() OVER (ORDER BY a DESC) AS row_num FROM some_table ) ranked_table WHERE row_num = 1;
- 如果存在多个
a等于最大值的行,ROW_NUMBER()会随机返回其中一行;若想返回所有最大值对应的行,将ROW_NUMBER()替换为RANK()即可。
方法2:ORDER BY + LIMIT(简单高效)
如果只需要一行结果,这种写法最简洁,若数据库对a建有索引,甚至可以直接定位到最大值行,无需全表排序:
SELECT a, b FROM some_table ORDER BY a DESC LIMIT 1;
示例验证
针对你的示例表:
| a | b | |---+-------| | 1 | red | | 1 | red | | 2 | green | | 2 | green |
使用上述两种方法,都会得到期望结果:
| a | b | |---+-------| | 2 | green |
内容的提问来源于stack exchange,提问作者Cigarette Smoking Man
相关产品推荐
相关产品推荐

