在多对多关系 MySql DB 中,我需要选择属于列表中类别(下例中 ID 为 9,10 的类别)的所有资源(带标题的文档)。
这是模型:
但是,这很重要:对于每个资源,我还想获得该资源与其关联的所有类别 - 而不仅仅是查询的类别...... 因此,如果带有 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/