You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将主表与存储元数据的另一张表关联合并且避免主数据重复

多表一对多关联查询主表字段去重方案

你遇到的重复问题是INNER JOIN关联一对多关系的表时的正常表现,要实现主表字段仅首行显示,可通过以下方案实现:

MySQL 8.0+ 版本(支持窗口函数)

核心逻辑是通过ROW_NUMBER()窗口函数给同主表ID的元数据行生成序号,仅序号为1的行返回主表字段值:

USE test;
SELECT
  CASE WHEN mm.row_num = 1 THEN m.id ELSE NULL END AS id,
  CASE WHEN mm.row_num = 1 THEN m.body ELSE NULL END AS body,
  CASE WHEN mm.row_num = 1 THEN m.title ELSE NULL END AS title,
  CASE WHEN mm.row_num = 1 THEN m.`time` ELSE NULL END AS `time`,
  -- 输出所有元数据字段,可按需替换为指定字段
  mm.* 
FROM (
  SELECT 
    *,
    ROW_NUMBER() OVER (PARTITION BY ref ORDER BY id) AS row_num
  FROM main_meta
  WHERE ref = 1
) mm
INNER JOIN main m ON mm.ref = m.id;
  • 可通过修改ORDER BY后的字段调整元数据的排序规则
  • 不需要展示的元数据字段可直接替换mm.*为指定字段列表

MySQL 5.x 兼容版本

通过自定义变量实现序号计数功能:

USE test;
SELECT id, body, title, `time`, /* 按需填写需要保留的元数据字段,剔除temp_row */
FROM (
  SELECT
    CASE WHEN @row = 1 THEN m.id ELSE NULL END AS id,
    CASE WHEN @row = 1 THEN m.body ELSE NULL END AS body,
    CASE WHEN @row = 1 THEN m.title ELSE NULL END AS title,
    CASE WHEN @row = 1 THEN m.`time` ELSE NULL END AS `time`,
    mm.*,
    @row := @row + 1 AS temp_row
  FROM main_meta mm
  INNER JOIN main m ON mm.ref = m.id
  CROSS JOIN (SELECT @row := 1) init_var
  WHERE mm.ref = 1
  ORDER BY mm.id
) t;

注:该需求属于展示层逻辑,更推荐在业务代码中对JOIN后的原始结果做二次处理,灵活性更高且不需要修改查询逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 07:27:07