一尘不染

MySQL选择多对多的位置

sql

我在使用SQL查询时遇到问题。我的架构描述了很多在文章之间多对多的关系articles表和类别在categories表-与中间表article_category它有一个idarticle_idcategory_id场。

我想选择所有只有id1和类别的文章2。不幸的是,该查询还将选择除其他类别外的所有具有这些类别的文章。

例如,这是SQL的示例输出( 出于描述目的显示类别
)。您可以看到,尽管查询选择了ID为10的文章,11但尽管有一个额外的类别,它也选择了ID为的文章。

+-------+------------+
| id    | categories |
+-------+------------+
| 10    | 1,2        |
| 11    | 1,2,3      |
+-------+------------+

这是我希望通过选择仅包含类别1和的文章来实现的输出2

+-------+------------+
| id    | categories |
+-------+------------+
| 10    | 1,2        |
+-------+------------+

同样的,这就是我想要的选择,只有类的文章来实现输出123

+-------+------------+
| id    | categories |
+-------+------------+
| 11    | 1,2,3      |
+-------+------------+

这是我编写的SQL。要实现上述目标,我缺少什么?

SELECT articles.id
FROM articles
WHERE EXISTS (
    SELECT 1
    FROM article_category
    WHERE articles.id = article_id AND category_id IN (1,2)
    GROUP BY article_id
)

非常感谢!


阅读 140

收藏
2021-05-23

共1个答案

一尘不染

假设您想要的不仅仅是文章的ID:

SELECT a.id
      ,a.other_stuff
  FROM articles a
  JOIN article_category ac
    ON ac.article_id = a.id
GROUP BY a.id
HAVING GROUP_CONCAT(DISTINCT ac.category_id ORDER BY ac.category_id SEPARATOR ',') = '1,2'

如果您想要的只是文章的ID,请尝试以下操作:

SELECT article_id
  FROM article_category 
GROUP BY article_id
HAVING GROUP_CONCAT(DISTINCT category_id ORDER BY category_id SEPARATOR ',') = '1,2'

请访问http://sqlfiddle.com/#!2/9d213/4实际操作

还应该补充一点这种方法的优点是它可以支持检查任何数量的类别,而不必更改查询。只需将“
1,2”设置为字符串变量,然后更改传递给查询的内容即可。因此,您可以通过传递字符串“ 1,2,7”来轻松搜索具有类别1、2和7的文章。无需其他联接。

2021-05-23