2011-12-30 25 views
4

關係(我有甚解釋這個問題很難)SQL,比較安置在多個鏈接表

我有5個表,A,​​,ZBZB

​​表示AZ之間的多對多關係。 BZ表示BZ之間的多對多關係。

我想的結果集是A B其中B被鏈接到一個給定A的全套Z

所以,讓我們說,Z是一個標籤表,包含:

Tag1 
Tag2 
Tag3 

A是一個對象表,包含:

ObjectA 
ObjectB 
ObjectC 

B是一個小部件表,包含:

WidgetX 
WidgetY 
WidgetZ 

​​co ntains:

ObjectA Tag1 
ObjectA Tag2 
ObjectB Tag3 
ObjectC Tag2 
ObjectC Tag3 

BZ包含:

WidgetX Tag1 
WidgetX Tag2 
WidgetY Tag2 
WidgetY Tag3 
WidgetZ Tag3 

我希望我的結果設置爲:

ObjectA WidgetX 
ObjectB WidgetY 
ObjectB WidgetZ 
ObjectC WidgetY 

這是可行的查詢,或者我應該拉回來一些中間套數據並在代碼中迭代?

回答

3

好的,主要的編輯根據您的反饋來調整它。這是一個有點缺憾,但在這裏你去:

select distinct 
    x.aid, 
    x.bid 
from 
    (select 
     az.aid, 
     bz.bid, 
     (select COUNT(1) from az az1 where az1.aid = az.aid) as acount, 
     (select COUNT(1) from bz bz1 where bz1.zid in (select zid from az az1 where az1.aid = az.aid) and bz1.bid = bz.bid) as bcount 
    from 
     az 
     inner join bz on 
      az.zid = bz.zid 
    ) x 
where 
    x.acount = x.bcount 

它使用子查詢討厭得到正確的計數,然後限制根據您的標準我們的行集。

+0

這不是正確的結果集。 ObjectA鏈接到Tag1和Tag2。 WidgetY未鏈接到Tag1,因此ObjectA到WidgetY無效。 – 2011-12-30 19:52:51

+0

@JacobG - 儘量在將來使用更好的表名和實際數據,相信它或不是這些例子使得幫助更加困難。 – JonH 2011-12-30 19:54:41

+0

@JacobG - 好吧,修正是正確的...讓我知道,如果這對你有用。 – Eric 2011-12-30 20:58:57

3

主要編輯:

隨着舍甫琴科正確地指出,我有堅持錯誤的結束我先走了。這應該會做得更好:

select a, b.b 
from az cross join b 
left outer join bz on az.z = bz.z and b.b = bz.b 
group by a, b.b 
having sum(case when bz.b is null then 1 else 0 end) = 0 

交叉連接建立了一個表,它表示每個b都滿足AZ中每個a的條件的假設。左外連接檢查這個假設,並在該假設失敗的bz.b列中留下空值。有條款排除那些包含一個或多個這種空值的a-b配對。

+0

從我如何理解問題出發,對象的標記集應該是小部件的子集,以便對象與小部件相匹配。您的查詢將返回太多匹配。 – 2011-12-30 20:58:35

+1

+1,我正在考慮這件事情,然後放棄嗜睡。只有我在考慮交叉連接到'(從bz選擇不同的b)'而不是'b',但是這不會影響結果,並且可能效率較低。 – 2011-12-31 14:03:18

+0

+1這個也適用。儘管這比Eric的解決方案慢了幾個數量級。我玩的好策略。謝謝! – 2012-01-03 15:51:11