mysql - 选择多对多关系中的所有相关值

标签 mysql sql many-to-many

在多对多关系 MySql DB 中,我需要选择属于列表中类别(下例中 ID 为 9,10 的类别)的所有资源(带标题的文档)。

这是模型:

enter image description here

但是,这很重要:对于每个资源,我还想获得该资源与其关联的所有类别 - 而不仅仅是查询的类别...... 因此,如果带有 title: title_1 的资源与 id 为 9 和 10 的类别相匹配,但如果该资源实际上也有类别 11 和 12,我想获取该信息。

因此,对于要求类别匹配 9 或 10 的资源的查询,我需要该资源及其所有相关类别。即我需要这样的资源的信息是:

资源标题:title_1 类别:9,10,11,12

即使我只指定它需要在查询中匹配 9 和 10 ...

这样做的原因是,如果用户基于几个类别进行搜索,结果仍应提供有关该对象的所有信息以及其上设置的所有类别。

我目前的情况是这样的:

SELECT
     r.title,
      cr.category_id
FROM
     category_resource cr
          INNER JOIN resource r
          ON cr.resource_id = r.id
WHERE cr.category_id IN (9,10)

这为我提供了带有这些资源标记的行,从 5000 行的数据库中非常快(大约 10 毫秒)。结果是 3 个标题:

title_1,类别:9 title_1,类别 10 title_2,类别:10

即,我得到了 title_1 的两个结果,因为它同时具有类别 9 和 10。但我只得到这两个类别,因为它们在查询中。但这并没有给我与资源 title_1 关联的其他类别。

请注意,我以前问过类似的问题,但不完全是。我得到了那个解决它的答案。但它变得太复杂了,我需要重新措辞并赋予它不同的重点。重点在这里:我需要获取此信息,但它也必须几乎与我当前使用的更简单的查询一样快,即大约 10 毫秒。这可能要求很多,但与此同时,对于数据库来说,这个要求对我来说似乎并不太牵强?即获取符合条件的项目,并从多对多关系表中获取与 in 关联的所有值......

作为这方面的专家还差得很远,但在我看来,关系数据库应该用来处理关系查询……所以我觉得必须有一个简单有效的解决方案来解决这个问题,我只是希望我能解释清楚了……

最佳答案

您可以使用 Self-Join 来完成此操作:

这是一个有效的 sqlfiddle:http://sqlfiddle.com/#!2/1826f/6

您已经加入 category_resource 以限制为 (9,10),因此我们加入它的副本并获得所有匹配的结果:

SELECT
     r.title,
      cr2.category_id
FROM
     category_resource cr
INNER JOIN resource r
ON cr.resource_id = r.id
INNER JOIN category_resource cr2 on cr2.resource_id = r.id
WHERE cr.category_id IN (9,10)
GROUP BY cr2.category_id,r.title
ORDER BY r.title

根据评论编辑: 如果您需要所有类别 (9,10),您可以将其更改为 self-join AGAIN as cr3:

SELECT
 r.title,
 cr2.category_id
FROM
 category_resource cr
INNER JOIN resource r
ON cr.resource_id = r.id
INNER JOIN category_resource cr2 on cr2.resource_id = r.id
INNER JOIN category_resource cr3 on cr3.resource_id = r.id
WHERE cr.category_id = 9
and cr3.category_id = 10
GROUP BY cr2.category_id,r.title
ORDER BY r.title

sqlfiddle:http://sqlfiddle.com/#!2/1826f/11

或者这里是使用 HAVING 的版本:http://sqlfiddle.com/#!2/1826f/12

SELECT
 r.title,
 cr2.category_id
FROM
 category_resource cr
INNER JOIN resource r
ON cr.resource_id = r.id
INNER JOIN category_resource cr2 on cr2.resource_id = r.id
WHERE cr.category_id IN (9,10)
GROUP BY cr2.category_id,r.title
HAVING count(cr.category_id)=2
ORDER BY r.title

关于mysql - 选择多对多关系中的所有相关值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21415324/

相关文章:

python - 从多对多字段中获取对象

nhibernate - 如何处理 API 中的多对多关系

mysql - 如何在联合中使用 case 语句

php - 如何在php中获取第一条和最后一条记录

sql - 将列默认值绑定(bind)到 SQL 2005 中的函数

java - 尝试使用生成的命名查询时出现 sqlException 错误

php - SELECT DISTINCT 仍然显示重复项

python - 具有额外属性的多对多关系 Django 模型

mysql - SQL 性能 UNION 与 OR

MySQL存储函数,如何检查没有行而不产生警告?