2015-11-30 93 views
0

我需要實現一個函數,它返回安裝不屬於的所有網絡。 以下是我的表,例如,如果我的安裝ID是1,並且我需要安裝不是其中一部分的所有網絡ID,則結果將僅爲[9]MySQL兩個表相交

network_id | installation_id 
------------------------------- 
    1  |  1 
    3  |  1 
    2  |  1  
    2  |  2 
    9  |  2 
    2  |  3  

我知道這可以用連接查詢解決,但我不知道如何實現它爲同一張表。這是我到目前爲止嘗試過的。

select * from network_installations where installation_id = 1; 

network_id | installation_id 
------------------------------- 
    1  |  1 
    2  |  1 
    3  |  1 

select * from network_installations where installation_id != 1; 

network_id | installation_id 
------------------------------- 
    9  |  2 
    2  |  2 
    2  |  3 

兩個表的交叉將導致預期的應答,即[9]。但是,雖然我們有union,intersect不在mysql中。對於找到上述兩個查詢的intersection或者使用single query using join來實現它的提示將非常感謝。

回答

1

要做到這一點,最好的辦法是使用network表(我相信存在):

select n.* 
from network n 
where not exists (select 1 
        from network_installation ni 
        where ni.network_id = n.network_id and 
         ni.installation_id = 1 
       ); 

如果,不知何故,你沒有網絡表,可以更換from子句:

from (select distinct network_id from network_installation) n 

編輯:

爲此,您可以在沒有子查詢單查詢,但join是多餘的。只需使用group by

select ni.network_id 
from network_installation ni 
group by ni.network_id 
having sum(ni.installation_id = 1) = 0; 

having條款計數爲每個網絡ID的定安裝匹配的數目。 = 0是說沒有。

+0

這是一個很好的一個。我有網絡表,查詢結果如我所料。但我想在一個選擇(在連接的幫助下)做到這一點。那可能嗎? @Gordon Linoff – DhiwaTdG

+0

只有一個詞,「真棒」。與它鬥爭了將近幾個小時。如果你不介意,你能否向我解釋查詢的最後一行。 – DhiwaTdG

+0

完美。謝謝。 – DhiwaTdG

1

使用OUTER JOIN另一種解決方案:

SELECT t1.network_id, t1.installation_id, t2.network_id, t2.installation_id 
FROM tab t1 LEFT JOIN tab t2 
    ON t1.network_id = t2.network_id AND t2.installation_id = 1 
WHERE t2.network_id IS NULL 

您可以檢查在http://www.sqlfiddle.com/#!9/4798d/2

+0

我已經嘗試過你的方法。由於我沒有network_id爲空的記錄,查詢不起作用。 – DhiwaTdG

+0

@DhiwaTdG它應該工作,因爲它利用了'LEFT JOIN'。將有一個記錄'network_id IS NULL'。檢查[這裏](http://www.sqlfiddle.com/#!9/4798d/2) –

0
select * 
from network_installations 
where network_id in 
    (select network_id 
    from network_installations 
    where installation_id = 1 
    group by network_id)