2009-09-17 33 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); 
相關問題