2009-09-17 30 views
0

我有2个表:组和组。两者都使用第三个表set_has_groups进行连接。 我想获得集,都集团我指定做着选择与多对多连接表中所有组匹配的记录

一种方式这将是

SELECT column1, column2 FROM sets WHERE 
id IN(SELECT set_id FROM set_has_group WHERE group_id = 1) 
AND id IN(SELECT set_id FROM set_has_group WHERE group_id = 2) 
AND id IN(SELECT set_id FROM set_has_group WHERE group_id = 3) 

显然这不是最漂亮的解决方案

我也试过这个:

SELECT column1, column2 FROM sets WHERE 
id IN(SELECT set_id FROM set_has_group WHERE group_id IN(1,2,3) GROUP BY group_id 
HAVING COUNT(*) = 3 

这看起来更漂亮,但问题是它需要永远执行。 第一次查询运行时间为200毫秒,第二次查询时间超过1分钟。

任何想法为什么这是?

===更新: 我打这个多一些,我修改了2次这样的查询

SELECT columns FROM `set` WHERE id IN(
    select set_id FROM 
     (
     SELECT set_id FROM set_has_group 
     WHERE group_id IN(1,2,3) 
     GROUP BY set_id HAVING COUNT(*) = 3 
    ) as temp   
) 

这是真的快 这是相同的作为第二查询之前只是我包它在另一个临时表 很奇怪

+0

是否设置组的集合或组的集合,或两者的集合?你的命名有点混乱。 – 2009-09-17 19:27:20

+0

集是主要的数据模型,他们可能被'标记'属于几个组 我试图找到属于组1,2和3的集 – MarcS 2009-09-17 19:29:08

回答

1

我怀疑第二个查询中的一个小mistyping。

真的,我不确定。第二个查询可能是通过全表扫描执行的。同时,第一个“IN”实际上变成了“EXISTS”。所以,你可以尝试使用“存在”。例如:

... 
where 3 = (select count(*) from set_has_group 
    where group_id in (1, 2, 3) and set_id = id 
    group by set_id) 
0

假设SQL Server中,这里是一个工作示例使用JOIN应该工作比你使用,只要你有正确设置主键和外键的IN子句更好。我已经加入了5组到3组,但是组4和5不是组3的一部分,并且不会在答案中显示。但是,这种查询是不可扩展(为前。找到4组,5,7,8和13将要求修改代码,除非你解析输入PARAMS到表变量)

set nocount on 

declare @sets table 
(
Id INT Identity (1, 1), 
Column1 VarChar (50), 
Column2 VarChar (50) 
) 

declare @Set_Has_Group table 
(
    Set_Id Int, 
    Group_Id Int 
) 

insert into @sets values (newid(), newid()) 
insert into @sets values (newid(), newid()) 
insert into @sets values (newid(), newid()) 
insert into @sets values (newid(), newid()) 
insert into @sets values (newid(), newid()) 

update @sets set column1 = 'Column1 at Row ' + Convert (varchar, id) 
update @sets set column2 = 'Column2 at Row ' + Convert (varchar, id) 

insert into @Set_Has_Group values (1, 1) 
insert into @Set_Has_Group values (1, 2) 
insert into @Set_Has_Group values (1, 3) 
insert into @Set_Has_Group values (2, 1) 
insert into @Set_Has_Group values (2, 2) 
insert into @Set_Has_Group values (2, 3) 
insert into @Set_Has_Group values (3, 1) 
insert into @Set_Has_Group values (3, 2) 
insert into @Set_Has_Group values (3, 3) 
insert into @Set_Has_Group values (4, 1) 
insert into @Set_Has_Group values (4, 2) 
insert into @Set_Has_Group values (5, 1) 
insert into @Set_Has_Group values (5, 2) 

/* your query with IN */ 
SELECT column1, column2 FROM @sets WHERE 
id IN(SELECT set_id FROM @set_has_group WHERE group_id = 1) 
AND id IN(SELECT set_id FROM @set_has_group WHERE group_id = 2) 
AND id IN(SELECT set_id FROM @set_has_group WHERE group_id = 3) 

/* my query with JOIN */ 
SELECT * -- Column1, Column2 
FROM @sets sets 
WHERE 3 = (
    SELECT Count (1) 
    FROM @Set_Has_Group Set_Has_Group 
    WHERE 1=1 
     AND sets.Id = Set_Has_Group.Set_Id 
     AND Set_Has_Group.Group_ID IN (1, 2, 3) 
    Group by Set_Id 
    ) 
0

下面是一个使用的解决方案不相关的子查询和否GROUP BY

SELECT column1, column2 
FROM sets 
WHERE id IN (
    SELECT g1.set_id FROM set_has_group g1 
    JOIN set_has_group g2 ON (g1.set_id = g3.set_id) 
    JOIN set_has_group g3 ON (g1.set_id = g3.set_id) 
    WHERE g1.group_id = 1 AND g2.group_id = 2 AND g3.group_id = 3); 
相关问题