简体   繁体   中英

MySQL intersection of two tables

I need to implement a function which returns all the networks the installation is not part of. Following is my table and for example if my installation id is 1 and I need all the network ids where the installation is not part of then the result will be only [9] .

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

I know this could be solved with a join query but I'm not sure how to implement it for the same table. This is what I've tried so far.

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

The intersection of the two tables will result the expected answer, ie [9] . But though we have union , intersect is not present in mysql. A solution to find the intersection of the above two queries or a tip to implement it with a single query using join will be much appreciated.

The best way to do this is to use a network table (which I presume exists):

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
                 );

If, somehow, you don't have a network table, you can replace the from clause with:

from (select distinct network_id from network_installation) n

EDIT:

You can do this in a single query with no subqueries, but a join is superfluous. Just use group by :

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

The having clause counts the number of matches for the given installation for each network id. The = 0 is saying that there are none.

Another solution using 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

You can check at http://www.sqlfiddle.com/#!9/4798d/2

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM