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

MySQL中通过子查询与Union关联两表的问题排查及修正

问题分析

你的原SQL逻辑完全偏离需求:

  • 子查询里的LEFT JOIN部分会返回所有table_1的id(左连接不管是否匹配table_2,都会保留主表的全部记录)
  • 再通过UNION ALL追加table_2中deleted='0'的table_1_id,最终子查询结果包含了几乎所有table_1的id,外层查询自然会返回全部主表数据,完全没起到筛选作用。
修正方案

推荐两种简洁且符合需求的写法:

方法1:LEFT JOIN + 条件过滤

SELECT DISTINCT t1.* 
FROM table_1 t1
LEFT JOIN table_2 t2 ON t1.id = t2.table_1_id
WHERE t2.table_1_id IS NULL -- 未出现在子表中的主表数据
   OR t2.status = 0; -- 已关联子表且status=0的主表数据

添加DISTINCT是为了避免子表中存在多条关联同一主表id的记录时,主表数据被重复返回;如果你的业务场景不会出现这种情况,可以去掉DISTINCT

方法2:NOT EXISTS + EXISTS 组合判断

SELECT t1.* 
FROM table_1 t1
WHERE NOT EXISTS ( -- 未出现在子表中的数据
    SELECT 1 FROM table_2 t2 WHERE t2.table_1_id = t1.id
)
OR EXISTS ( -- 已关联子表且status=0的数据
    SELECT 1 FROM table_2 t2 WHERE t2.table_1_id = t1.id AND t2.status = 0
);

这种写法无需去重,因为EXISTS仅做存在性判断,不会导致主表数据重复。

额外补充

如果需要同时过滤子表中已删除的记录(比如只考虑deleted='0'的子表数据),可以在关联条件中追加过滤规则,以方法1为例:

SELECT DISTINCT t1.* 
FROM table_1 t1
LEFT JOIN table_2 t2 ON t1.id = t2.table_1_id AND t2.deleted = '0'
WHERE t2.table_1_id IS NULL 
   OR t2.status = 0;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 12:52:52