SQL查询以获得预期的结果

时间:2011-02-18 17:31:06

标签: sql mysql join

这是我的数据库架构

Table_A
-id 
-status

Table_B
-id

Table_A_has_B
-id
-id_A
-id_B

我需要从Table_B中选择所有记录,其中所有关联的Table_A记录都有status=1,如果Table_B记录没有任何关联的Table_A也应该被选中。

测试用例:

CREATE TABLE table_a (id int(2),status int(1));
INSERT INTO table_a (id, status)
VALUES (1,1),(2,0),(3,1),(4,1),(5,1);

CREATE TABLE table_b (id int(2));
INSERT INTO table_b (id) VALUES (1),(2),(3),(4);

CREATE TABLE table_a_has_b (id int(2),id_A int(2),id_B int(2));
INSERT INTO table_a_has_b (id, id_A, id_B)
VALUES(1, 1, 1),(2, 2, 1),(3, 3, 1),(4, 4, 2),(5, 5, 2),(6, 3, 4),(7, 4, 4);

查询应选择:

+----+
|b.id|
+----+
|   2|
|   3|
|   4|
+----+
  • 不应选择Id 1,因为其table_a记录之一的状态为status = 0
  • 应该选择Id 2和4,因为它的所有table_a记录都具有status = 1
  • 应该选择ID 3,因为没有关联table_a记录,相同标准的另一个观点是:应该选择Id 3,因为没有任何table_a记录,其中status = 0

3 个答案:

答案 0 :(得分:3)

编辑答案 -

select b.* from table_B b 
left outer join table_A_has_B ab on ab.id_B = b.id
where ab.id in (
    select id from table_A_has_B ab
    where (id_A in (select id from table_A where status = 1 ))
)
or b.id not in 
(select id_B from table_A_Has_B )

旧答案 -

select b.* from table_B b
left outer join table_A a on b.id = a.id
where a.status = 1 or a.id is null

答案 1 :(得分:2)

Select ...
From Table_B As B
    Left Join   (
                Select AB.id_B, A.id, A.status
                From Table_A_has_B As AB
                    Join Table_A As A
                        On A.id = AB.id_A
                Where A.status = 1
                ) As Z
        On Z.id_B = B.id

原帖的这部分内容不明确:if a Table_B record hasn't any associated Table_A also should be selected.

如果您只想要Table_B中的行,那么:

Select B.*
From Table_B As B
Where Exists    (
                Select 1
                From Table_A_has_B As AB
                    Join Table_A As A
                        On A.id = AB.id_A
                Where A.status = 1
                    And AB.id_B = B.id
                )

如果您想要来自Table_ B的行,其中Table_A_has_B中的行没有给定id_B,或者如果有行,则必须与Table_A项目关联status 1}}是1,然后是:

Select B.*
From Table_B As B
Where Exists    (
                Select 1
                From Table_A_has_B As AB
                    Join Table_A As A
                        On A.id = AB.id_A
                Where A.status = 1
                    And AB.id_B = B.id
                )
    Or Not Exists   (
                    Select 1
                    From Table_A_has_B As AB
                    Where AB.id_B = B.id
                    )

如果你想要的是Table_A中的行,但只有状态为1而其他所有行为null,那么我提供的第一个查询就是解决方案。为我们提供一些预期的输出结果显然会有很大的帮助。

修改OP的给定更新

鉴于您的更新,现在只清楚您要实现的目标,请执行以下操作:

Select B.id
From Table_B As B
Where Not Exists    (
                    Select 1
                    From Table_A_has_B As AB
                        Join Table_A As A
                            On A.id = AB.id_A
                    Where A.status <> 1
                        And AB.id_B = B.id
                    )

答案 2 :(得分:0)

通过改写你的需求声明来选择table_B,它没有关联的table_A,状态为&lt;&gt; 1.我来到以下查询语句:

select distinct b.* 
from table_B b
left outer join table_A_has_B ab on ab.id_B = b.id
left outer join table_A a on a.id = ab.id_A and a.status <> 1
where a.id is null

select b.* 
from table_B b
where not exists (select null from table_A_has_B ab 
inner join table_A a on a.id = ab.id_A and a.status <> 1
where ab.id_B = b.id)