我有三个这样的表(简化版):
Object
---------------
ID | ObjectName
---------------
Category
-----------------
ID | CategoryCode
-----------------
ObjectCategory
---------------------
ObjectID | CategoryID
---------------------
如何为所有不属于某些CategoryCode
的对象选择ObjectName
和CategoryCode
?我不能只在所有三个表的 JOIN
ed 查询中添加一个 WHERE
子句,因为它会忽略预期的限制,只要一个对象至少属于一个允许的对象类别代码
。
编辑:我还需要从 Category
表中选择 CategoryCode
,仅在 Object
表中选择是不够的
最佳答案
这是NOT EXISTS
的解决方案
select o1.*, c1.*
from object o1
inner join object_category oc1
on o1.id = oc1.object_id
inner join category c1
on oc1.category_id = c1.id
where not exists (
select null
from object_category oc2
inner join category c2
on oc2.category_id = c2.id
where c2.name in ('code1', 'code1')
and oc2.object_id = o1.id
)
不费吹灰之力就可以将其重写为等效的 NOT IN 子查询(未显示)
在 mySQL 中,子查询,尤其是相关子查询,如 EXISTS 和 NOT IN 解决方案,可能会非常慢。替代方法是尝试 LEFT JOIN 和 GROUP BY:
select o1.*, c1.*
from object o1
inner join object_category oc1
on o1.id = oc1.object_id
inner join category c1
on oc1.category_id = c1.id
left join object_category oc2
on o1.id = oc2.object_id
left join category c2
on oc2.category_id = c2.id
and c2.name in ('code1', 'code1' )
group by o1.id, c1.id
having count(c2.id) = 0
关于sql - 限制多对多连接查询的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2274114/