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

MySQL如何通过多个1:n关联表查询指定分类下的可用标签

问题说明

现有MySQL数据库包含Categories、Posts、Tags三张数据表,Posts表与Tags、Categories表均为1:N关联关系:单篇Post仅对应唯一category、唯一tag。要求不直接关联Categories与Tags表的前提下,查询指定分类下的所有可用标签。
示例表结构与测试数据如下:

-- Posts表
post ID | category ID | tag ID
----------------------------
1       | 1           | 1
2       | 1           | 2
3       | 2           | 1
4       | 3           | 3

-- Categories表
category ID | name
--------------------
1           | video
2           | image
3           | code

-- Tags表
tag ID | name
--------------------
1      | funny
2      | info
3      | script

预期查询效果:

查询分类为video时,返回标签funny、info;查询分类为code时,仅返回标签script。


实现方案

核心思路是用Posts表做两表的关联中转,全程不写Categories和Tags的直接关联条件,两种常用写法都能满足要求:

写法1:JOIN关联(推荐,可读性更好)

SELECT DISTINCT t.`name` AS tag_name
FROM Categories c
INNER JOIN Posts p
  ON c.`category ID` = p.`category ID`
INNER JOIN Tags t
  ON p.`tag ID` = t.`tag ID`
WHERE c.`name` = 'video'; -- 替换此处的分类名即可查询对应分类的标签

注意点:

  • 因为示例里的字段名带空格,所有字段名都加了反引号转义,如果你实际建表用的是无空格的命名(比如category_id),调整反引号内的字段名即可
  • 加DISTINCT是为了去重:如果同一个分类下有多篇文章绑定了同一个标签,不会返回重复的标签名
  • 关联路径是Categories -> Posts -> Tags,没有直接关联Categories和Tags,完全符合要求

写法2:子查询嵌套

习惯写子查询的话可以用这个写法,InnoDB引擎下执行效率和JOIN写法基本一致:

SELECT `name` AS tag_name
FROM Tags
WHERE `tag ID` IN (
  SELECT DISTINCT `tag ID`
  FROM Posts
  WHERE `category ID` = (
    SELECT `category ID`
    FROM Categories
    WHERE `name` = 'video' -- 替换为目标分类名
  )
);

结果验证

用测试数据跑上述SQL:

  • 把WHERE条件的分类名改为video,返回结果为funny、info
  • 把WHERE条件的分类名改为code,返回结果为script
    完全匹配预期效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:12:21