You need to enable JavaScript to run this app. INNER JOIN查询如何有效消除结果集中的冗余条目
优惠活动
大模型
产品
解决方案
定价
更多

INNER JOIN查询如何有效消除结果集中的冗余条目

冗余问题的本质

当前结果中出现stipend重复的根源,是moniker_tbl和student_tbl的关联关系是 一对多:同一个学生姓名(name字段)在moniker_tbl中对应多条昵称记录,和student_tbl里单条助学金记录匹配后,自然会生成多份带着相同stipend的冗余条目。

避坑提醒:直接在原JOIN查询的结果上套DISTINCT完全达不到效果——不同的昵称本身就是不同的行内容,DISTINCT会把所有nickname+stipend的组合都保留,根本没法实现 每个学生只展示一条关联昵称 的需求。

可行的解决思路

核心是从关联的源头做去重:先对moniker_tbl按关联键(name字段)做筛选,每个name只保留1条需要展示的昵称,再和student_tbl做内连接,彻底切断多对一的关联冗余。

通用兼容方案(支持所有MySQL版本)

通过子查询对moniker_tbl按name分组聚合,每个name取出一条目标昵称后再关联:

SELECT t1.nickname, t2.stipend
FROM 
  -- 先按name聚合,每个name只留一条昵称
  (SELECT name, MIN(nickname) AS nickname 
   FROM moniker_tbl 
   GROUP BY name) AS t1
INNER JOIN student_tbl AS t2
ON t1.name = t2.name;

这里用MIN(nickname)是取每个name下字典序最靠前的昵称,刚好匹配示例中选中"Jonny"作为John Doe对应昵称的预期输出。

如果需要自定义选取的昵称规则(比如取最新插入的那条记录对应的昵称),可以把聚合逻辑换成关联子查询实现:

SELECT t1.nickname, t2.stipend
FROM 
  (SELECT name, nickname 
   FROM moniker_tbl m1
   -- 取每个name下id最大的那条记录(也就是最新插入的)
   WHERE id = (SELECT MAX(id) FROM moniker_tbl m2 WHERE m2.name = m1.name)) AS t1
INNER JOIN student_tbl AS t2
ON t1.name = t2.name;

MySQL 8.0+ 优化方案

如果用的是支持窗口函数的数据库版本,可以用分区排序的方式筛选每个name下的第一条记录,执行效率比逐行关联子查询更高:

SELECT t1.nickname, t2.stipend
FROM 
  (SELECT 
     name, nickname,
     -- 按name分区,按id升序排序,每个分区的第一行标记rn=1
     ROW_NUMBER() OVER (PARTITION BY name ORDER BY id ASC) AS rn
   FROM moniker_tbl
  ) AS t1
INNER JOIN student_tbl AS t2
ON t1.name = t2.name
WHERE t1.rn = 1;

内容的提问来源于stack exchange,提问作者Sandeep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 09:36:07