限制多对多联合查询的结果

时间:2010-02-16 15:50:45

标签: sql mysql

我有三个这样的表(简化版):

Object
---------------
ID | ObjectName
---------------

Category
-----------------
ID | CategoryCode
-----------------

ObjectCategory
---------------------
ObjectID | CategoryID
---------------------

如何为属于某些ObjectName s的所有对象选择CategoryCodeCategoryCode?我不能在所有三个表的WHERE ed查询中添加JOIN子句,因为只要对象属于至少一个允许的CategoryCode,它就会忽略预期的限制。

编辑:我还需要从CategoryCode表中选择Category,仅Object表上的选择是不够的

2 个答案:

答案 0 :(得分:1)

以下是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

答案 1 :(得分:0)

SELECT ObjectName 
FROM Objects 
    WHERE ObjectID NOT IN (
           SELECT ObjectID 
           FROM ObjectCategory AS a 
           JOIN Category AS b 
                ON a.CategoryID = b.CategoryID
           WHERE CategoryCode = 'yourcodehere')

尚未测试过,但是这应该得到未连接到某个CategoryCode的对象的所有ID的名称