SQL查询如何限制Person列的唯一值数量以返回对应属性行
长表按维度唯一值数量截取全量关联记录的实现
问题背景
当前查询的是存储人员属性的长表,固定包含Person、Property、Value三列,全量返回的数据明细为:
- Jack对应两条属性:年龄52、车辆GAZ
- John对应两条属性:年龄42、车辆Audi
- Martin对应两条属性:年龄38、车辆BMW
实际需求是仅返回前2个不同Person值对应的全部关联属性记录,也就是拿到Jack、John名下共4条全量属性数据。
如果直接在原有查询后加LIMIT语法,只会按返回的物理行数做截断:因为单个人对应2条属性,LIMIT 2最终只会返回Jack的2条属性,完全达不到“取前2个不同Person的全量数据”的目标。
实现方式
核心思路是先锁定符合数量要求的Person集合,再关联回原长表匹配全量属性,常见两种可落地的写法:
- 子查询取目标Person集合后关联原表
先通过子查询提取排序后的前2个不重复Person值,和原表做内连接,匹配这些Person对应的所有关联记录:SELECT t.Person, t.Property, t.Value FROM person_attr_long_table t INNER JOIN ( -- 提取排序后前2个不重复的Person值 SELECT DISTINCT Person FROM person_attr_long_table ORDER BY Person LIMIT 2 ) target_person ON t.Person = target_person.Person; - 窗口函数标记Person序号后直接筛选
对支持窗口函数的SQL引擎,可以用密度排名函数给去重后的Person打连续序号,直接筛选符合序号要求的记录,不需要额外写关联逻辑:SELECT Person, Property, Value FROM ( SELECT Person, Property, Value, -- 按Person排序打不重复的连续序号 DENSE_RANK() OVER(ORDER BY Person) AS person_sort_rank FROM person_attr_long_table ) ranked_record WHERE person_sort_rank <= 2;
结果说明
两种写法最终都会返回4条符合要求的记录:Jack的年龄、车辆属性,John的年龄、车辆属性,彻底解决直接按行截断带来的筛选范围不全的问题。
内容的提问来源于stack exchange,提问作者Sebastian Richter
相关产品推荐
相关产品推荐

