2012-07-03 62 views
1

嗨,大家好我有一個表關係,其工作原理是這樣的(傳統)SQL查詢建設:檢查是否查詢結果是另一個

A有很多B和B有許多C的子集; A有許多C以及

現在我遇到了一個SQL,它將幫助我將所有B(Id的B簡化)映射到某個A(通過Id)和任何B有一個C的集合,這是答案的C的子集A.

我沒有拿出一個像樣的SQL專門爲第二部分,並想知道如果我可以得到任何提示/建議我怎麼能做到這一點。

感謝

編輯:

Table A 

Id  |.. 
------------ 
1  |.. 




Table B 

Id  |.. 
-------------- 
2  |.. 

Table A_B_rel 

A_id | B_id 
----------------- 
1  |  2 

C是一個奇怪的表。 C(單柱)的數據實際上只是上當的2相對錶A和B.所以它這樣

Table B_C_Table 

B_Id| C_Value 
----------------- 
2 | 'Somevalue' 

Table A_C_Table 

A_Id| C_Value 
------------- 
1 | 'SomeValue' 

所以我找了燒烤,其中有一定的A_C_Values的子集C_Values。

+1

也許你能舉個例子嗎?每個表格中的幾行都會執行,請嘗試http://sqlfiddle.com –

回答

1

是的,你的問題的第二部分有點棘手。我們一方面有B_C_Table,另一方面是A_C_Table的子集,其中A_ID是一個特定的ID。

現在,如果我們使用一個外連接,我們就能夠看到這B_C_Table行在A_C_Table不匹配:

SELECT * 
FROM B_C_Table bc 
    LEFT JOIN A_C_Table ac ON bc.C_Value = ac.C_Value AND ac.A_ID = @A_ID 

注意,它把ac.A_ID = @A_IDON條款是非常重要的而不是WHERE,因爲在後一種情況下,我們會過濾出不匹配的@A_ID行,這不是我們想要的。

下一步(實現最終查詢)將按B對行進行分組並計算行數。現在,我們將計算行的總數以及匹配行的的數量。

SELECT 
    bc.B_ID, 
    COUNT(*)  AS TotalCount, 
    COUNT(ac.A_ID) AS MatchCount 
FROM B_C_Table bc 
    LEFT JOIN A_C_Table ac ON bc.C_Value = ac.C_Value AND ac.A_ID = @A_ID 
GROUP BY bc.B_ID 

正如你可以看到,數場比賽中,我們簡單地計算ac.A_ID值:在沒有比賽的情況下,相應的列會NULL,因此不計算在內。如果B_C_Table中的某些行確實與A_C_Table的子集中的任何行不匹配,我們將會看到的不同的值爲TotalCountMatchCount

而這在邏輯上導致我們走向最後一步:比較這些數字。 (很明顯,如果我們可以獲取值,我們也可以將它們進行比較。)但WHERE子句中並沒有,因爲在WHERE中不允許使用聚合函數。它是HAVING子句,用於比較分組的行的值,也包括彙總值。所以......

SELECT 
    bc.B_ID, 
    COUNT(*)  AS TotalCount, 
    COUNT(ac.A_ID) AS MatchCount 
FROM B_C_Table bc 
    LEFT JOIN A_C_Table ac ON bc.C_Value = ac.C_Value AND ac.A_ID = @A_ID 
GROUP BY bc.B_ID 
HAVING COUNT(*) = COUNT(ac.A_ID) 

的計數值不是真正需要的,當然,當你刪除它們,你將能夠UNION與一個從A_B_rel選擇B_ID上面的查詢:

SELECT B_ID 
FROM A_B_rel 
WHERE A_ID = @A_ID 

UNION 

SELECT bc.B_ID 
FROM B_C_Table bc 
    LEFT JOIN A_C_Table ac ON bc.C_Value = ac.C_Value AND ac.A_ID = @A_ID 
GROUP BY bc.B_ID 
HAVING COUNT(*) = COUNT(ac.A_ID) 
+0

感謝您的驚人解釋和全面解答+1。 – user446923

1

也許這是你在找什麼:

SELECT B_id 
FROM A_B_rel 
WHERE A_id = <A ID> 

UNION 

SELECT a.B_Id 
FROM B_C_Table a 
LEFT JOIN A_C_Table b ON a.C_Value = b.C_Value AND b.A_Id = <A ID> 
GROUP BY a.B_Id 
HAVING COUNT(CASE WHEN b.A_Id IS NULL THEN 1 END) = 0 

第一SELECT得到其映射到特定A<A ID>是爲A ID輸入參數)所有B的,那麼我們釘到該結果設置任何附加B的其整套​​的是特定A(再次的​​的的子集,<A ID>作爲inpu t參數)。

+0

查詢的第一部分沒有問題。第二個是部分正確的,這就是問題所在。在你的情況下,如果來自A_C_Table的任何C_Value與B_C_table的C_Value相匹配,那麼它是真實的,但是我的方案是「全部」而不是「任何」。所以我只需要B_Id,那些B的C_Values是A的C_Values的子集。因此,A_C_Value是{0,1,2,3}和B_C_Values {0,1,2,9},因此它不匹配。但是,如果B_C_Value是{1,3}或者{0,2,3}等,那麼我需要這個B等等。 – user446923

+0

follow ups?:)謝謝 – user446923

+0

@ user446923我從字面上回來了,我正在看一看。 –

1

聽起來像是你需要考慮在雙重否定的方面,也就是說,應該不存在不具有匹配A_C任何B_C(我猜應該有至少一個B_C)。

所以,你可以試試

select B.B_id 
from Table_B B 
where exists (select 1 from B_C_Table BC 
        where BC.B_id = B.B_id) 
    and not exists (select 1 from B_C_Table BC 
        where BC.B_id = B.B_id 
        and not exists(select 1 from B_C_Table AC 
            join A_B_Rel ABR on AC.A_id = ABR.A_id 
            where ABR.B_id = B.B_id 
            and BC.C_Value = AC.C_Value)) 
相關問題