如何关联表并获取每组Priority最大值对应的人员信息?SQL问询
分组关联最高优先级人员的SQL查询方案
需求说明
需查询所有Groups表的Id、Name、Address,同时关联每组(GroupId对应)中Priority最高的人员姓名:
- 组内存在非
NULL优先级时,取优先级最高的记录; - 组内仅存
NULL优先级记录时,任选其一; - 优先级并列时,任选其一(可通过额外字段确保结果稳定)。
示例数据
Groups表
| Id | Name | Address |
|---|---|---|
| 1 | 研发部 | 科技大厦A座 |
| 2 | 人事部 | 行政楼3层 |
| 3 | 财务部 | 金融中心B区 |
People表
| Id | GroupId | Name | Priority |
|---|---|---|---|
| 1 | 1 | 张三 | 3 |
| 2 | 1 | 李四 | 5 |
| 3 | 1 | 王五 | NULL |
| 4 | 2 | 赵六 | NULL |
| 5 | 2 | 孙七 | NULL |
| 6 | 3 | 周八 | 2 |
| 7 | 3 | 吴九 | 2 |
预期结果
| Id | Name | Address | TopPerson |
|---|---|---|---|
| 1 | 研发部 | 科技大厦A座 | 李四 |
| 2 | 人事部 | 行政楼3层 | 赵六(或孙七) |
| 3 | 财务部 | 金融中心B区 | 周八(或吴九) |
通用解法(支持MySQL 8+、PostgreSQL、SQL Server等)
使用窗口函数ROW_NUMBER()实现分组排序并筛选首行:
SELECT g.Id, g.Name, g.Address, p.Name AS TopPerson FROM Groups g LEFT JOIN ( SELECT GroupId, Name, -- 按组划分,优先级降序排序,Id兜底确保并列时结果稳定 ROW_NUMBER() OVER (PARTITION BY GroupId ORDER BY Priority DESC, Id) AS rn FROM People ) p ON g.Id = p.GroupId AND p.rn = 1;
兼容旧版MySQL(5.x)解法
如果不支持窗口函数,可使用关联子查询+LIMIT:
SELECT g.Id, g.Name, g.Address, ( SELECT Name FROM People p WHERE p.GroupId = g.Id ORDER BY Priority DESC, Id LIMIT 1 ) AS TopPerson FROM Groups g;
关键逻辑说明
- NULL处理:
ORDER BY Priority DESC中,多数数据库默认将NULL视为比所有非NULL值小,因此非NULL优先级会优先被选中;仅当组内全为NULL时,才会返回其中一条。 - 并列任选:添加
Id作为次级排序字段,可避免并列时结果随机,确保每次查询返回同一记录(无需稳定结果可去掉)。
内容的提问来源于stack exchange,提问作者vkapadia
相关产品推荐
相关产品推荐

