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

SQL查询一对多关系中不含指定关联值的主表记录方法

查询不包含指定标签的多对多关联记录SQL实现

表结构与需求说明

  • 共三张表:Exercise存储练习记录,Tag存储标签,TagsExercises为中间关联表,实现练习与标签的多对多关系,单个练习可关联多个标签
  • 核心需求:返回完全未绑定指定标签的所有练习记录

示例数据

Exercise表内容:
Exercise 1
Exercise 2
Exercise 3

Tag表内容:
Tag 1
Tag 2

TagsExercises关联关系:
Exercise 1 - Tag 1
Exercise 1 - Tag 2
Exercise 2 - Tag 1
Exercise 3 - Tag 2

验证场景:查询不包含Tag 1的练习,预期返回结果仅为Exercise 3

原有SQL的错误原因

你之前编写的SQL是行级过滤逻辑:只要某条关联记录的标签ID不等于要排除的ID,该行就会被保留。比如Exercise 1同时关联Tag1和Tag2,其中关联Tag2的记录满足Tags.id NOT IN的判断条件,就会被错误返回,最终得到不符合预期的结果。

正确SQL写法

方案1:NOT EXISTS 反向判断(推荐,性能最优)

逻辑:直接筛选不存在「绑定了待排除标签」关联记录的练习

SELECT e.id 
FROM Exercise e
WHERE NOT EXISTS (
    SELECT 1 
    FROM TagsExercises te
    WHERE te.idExercise = e.id 
      AND te.idTag = '1' -- 此处替换为需要排除的标签ID
);

方案2:左连接+空值判断

逻辑:左连接练习与待排除标签的关联关系,筛选关联为空(即未绑定该标签)的练习

SELECT e.id
FROM Exercise e
LEFT JOIN TagsExercises te 
  ON e.id = te.idExercise 
  AND te.idTag = '1' -- 此处替换为需要排除的标签ID
WHERE te.idExercise IS NULL;

方案3:分组聚合判断

逻辑:按练习分组,统计每个练习绑定待排除标签的总次数,筛选次数为0的记录

SELECT e.id
FROM Exercise e
LEFT JOIN TagsExercises te 
  ON e.id = te.idExercise
GROUP BY e.id
HAVING SUM(te.idTag = '1') = 0; -- 此处替换为需要排除的标签ID

扩展说明

如果需要同时排除多个标签,仅需调整标签判断条件即可:

  • NOT EXISTS写法:将条件改为te.idTag IN ('1','2')(括号内为所有待排除的标签ID)
  • 聚合写法:将条件改为SUM(te.idTag IN ('1','2')) = 0
  • 不建议继续使用隐式逗号连接表的写法,统一使用显式JOIN语法可避免大量连接逻辑错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:03:29