如何筛选含指定标签的漫画并返回其全部关联标签?
筛选含指定标签的漫画并保留所有关联标签的解决方案
要实现筛选包含指定标签(比如racing)的漫画,同时返回该漫画的所有关联标签,你可以用以下几种高效的SQL写法:
方法一:使用EXISTS子查询(推荐,性能更优)
这种方式先筛选出符合标签条件的漫画ID,再关联所有标签进行拼接:
SELECT M.id AS `M.id`, M.title AS `M.title`, GROUP_CONCAT(T.name SEPARATOR ', ') AS tags FROM Manga M JOIN Manga_Tags_Association MTA ON M.id = MTA.manga_id JOIN Tags T ON MTA.tag_id = T.id WHERE EXISTS ( SELECT 1 FROM Manga_Tags_Association MTA_filter JOIN Tags T_filter ON MTA_filter.tag_id = T_filter.id WHERE MTA_filter.manga_id = M.id AND T_filter.name = 'racing' ) GROUP BY M.id, M.title;
方法二:使用GROUP BY + HAVING(逻辑直观)
通过分组后统计指定标签的出现次数,判断是否符合条件:
SELECT M.id AS `M.id`, M.title AS `M.title`, GROUP_CONCAT(T.name SEPARATOR ', ') AS tags FROM Manga M JOIN Manga_Tags_Association MTA ON M.id = MTA.manga_id JOIN Tags T ON MTA.tag_id = T.id GROUP BY M.id, M.title HAVING SUM(CASE WHEN T.name = 'racing' THEN 1 ELSE 0 END) > 0;
方法三:窗口函数实现(你提到的思路)
利用窗口函数按漫画ID分区拼接所有标签,再筛选目标标签:
WITH MangaWithTags AS ( SELECT M.id AS `M.id`, M.title AS `M.title`, T.name AS tag, GROUP_CONCAT(T.name SEPARATOR ', ') OVER (PARTITION BY M.id) AS tags FROM Manga M JOIN Manga_Tags_Association MTA ON M.id = MTA.manga_id JOIN Tags T ON MTA.tag_id = T.id ) SELECT DISTINCT `M.id`, `M.title`, tags FROM MangaWithTags WHERE tag = 'racing';
为什么你之前的尝试失败?
- 直接在
WHERE中过滤T.name = 'racing':会只保留该标签的关联记录,分组后自然只能得到单个标签。 - 试图在
WHERE或HAVING中用'racing' IN AllTags:GROUP_CONCAT生成的是字符串,不是集合,IN无法直接作用于字符串,所以这种写法不生效。 - 子查询关联标签时逻辑错误:需要用
EXISTS或计数的方式判断该漫画是否包含目标标签,而非直接检查拼接后的字符串。
内容的提问来源于stack exchange,提问作者M I P A
相关产品推荐
相关产品推荐

