查询共享一组关联的行

时间:2014-02-12 16:25:55

标签: mysql sql

我有三个表:ABCBAC有多对多的关系。

A >-< B >-< C

假设每个表都有一个名为id的主键列,并且连接表有两列[a_id,b_id]和[b_id,c_id]。

B中的同一行可以链接到AC中的两行。在C中找到共享B(一系列内连接)中特定行的行非常简单。

如果行ID为A,我想查询C中与B中与该行相关联的所有A行的所有行:< / p>

select id,
    (select count(*) from c
        inner join b_c on c.id = b_c.c_id
    ) as c_group,
    (select count(*) from c 
        inner join b_c on c.id = b_c.c_id
        inner join b on b.id = b_c.b_id
        inner join a_b on b.id = a_b.b_id
     where a_id = ?
    ) as a_c_group
from c 
where c_group <= a_c_group;

这可以通过SQL完成吗?我在MySQL工作,所以MySQL特定的解决方案没问题。

3 个答案:

答案 0 :(得分:1)

这将产生与所选A:

相关联的B的所有id
SELECT b_id FROM ab WHERE a_id = ?

所以你需要找到任何只与这些B id相关的C而不是其他的。这可以通过排除与其他B id匹配的所有C来完成:

SELECT c.id
FROM c
LEFT JOIN bc ON c.id = bc.c_id 
  AND bc.b_id NOT IN (SELECT b_id FROM ab WHERE a_id = ?)
WHERE bc.c_id IS NULL

答案 1 :(得分:0)

如果我正确理解了您的问题,您希望CB中具有匹配行的所有行反过来与A中指定的行ID匹配。

这应该这样做:

select
    c.*
from
    c
    join bc on c.id = bc.c_id
where
    exists (select 1
              from ab
             where ab.a_id = 123
                   and ab.b_id = bc.b_id)

这假设你的连接(桥)表名为abbc,并且你正在寻找一个123的a.id

SQLFiddle here

答案 2 :(得分:0)

解决方法是将B和C的内连接的计数与所有三个表的内连接进行比较。

SELECT ID
FROM C
WHERE (
  SELECT COUNT(*)
  FROM B_C
  WHERE C_ID = C.ID
) <= (
  SELECT COUNT(*)
  FROM B_C INNER JOIN A_B ON B_C.B_ID = A_B.B_ID 
  WHERE C_ID = C.ID AND A_ID = ?
);

这包括:

  1. 如果C没有关联的B,它应该出现在结果集中。
  2. 如果C关联的B与A没有关联,则它不会出现在结果集中。
  3. 如果A关联的B与C无关,但所有B的C关联,则C出现在结果集中。