SQL如何筛选不在「按名字取最大年龄」子查询结果的行及空集问题排查
问题原因
你现有查询返回空集的核心原因是 NOT EXISTS 子查询没有和外层查询的行做关联匹配:当前内层查询是独立返回所有first_name对应的最大年龄集合,只要内层有返回结果,外层的NOT EXISTS判断就会永远为假,最终查询结果自然为空。
最优实现方案
推荐两种适配不同场景的写法:
方案1:关联式NOT EXISTS写法(兼容所有SQL版本)
修正关联逻辑后即可实现需求:
SELECT t.first_name, t.age FROM taba t WHERE NOT EXISTS ( SELECT 1 FROM taba p WHERE p.first_name = t.first_name GROUP BY p.first_name HAVING MAX(p.age) = t.age );
逻辑说明:内层子查询会逐行判断外层当前记录是否是对应first_name分组下的最大年龄记录,匹配到就会被NOT EXISTS排除,最终返回的就是不属于最大年龄集合的记录。
方案2:窗口函数写法(性能更优,适合大数据量场景)
仅需单次扫描表即可完成计算,效率远高于子查询关联写法:
WITH ranked_data AS ( SELECT first_name, age, RANK() OVER (PARTITION BY first_name ORDER BY age DESC) AS age_rank FROM taba ) SELECT first_name, age FROM ranked_data WHERE age_rank > 1;
逻辑说明:用RANK()窗口函数给每个first_name分组内的记录按年龄倒序排名,排名为1的就是对应分组的最大年龄记录,筛选排名大于1的即可得到目标结果,同分组下有多个相同最大年龄的记录也会被全部排除。
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

