简体   繁体   English

SQL查询获得预期结果

[英]SQL query to get expected result

This is my DB schema 这是我的数据库架构

Table_A
-id 
-status

Table_B
-id

Table_A_has_B
-id
-id_A
-id_B

I need to select all records from Table_B, where all associated Table_A records has status=1 and if a Table_B record hasn't any associated Table_A also should be selected. 我需要从Table_B中选择所有记录,其中所有关联的Table_A记录的status=1均为status=1 ,如果Table_B记录没有任何关联的Table_A,则也应选择。

Test case: 测试用例:

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

The query should select: 查询应选择:

+----+
|b.id|
+----+
|   2|
|   3|
|   4|
+----+
  • Id 1 shouldn't be selected because one of its table_a records has status=0 不应选择ID 1,因为其table_a记录之一的状态为= 0
  • Id 2 and 4 are should be selected because all its table_a records has status=1 应该选择ID 2和ID 4,因为其所有table_a记录的状态均为= 1
  • Id 3 should be selected because don't has table_a records associated, another point of view for the same criterion is: Id 3 should be selected because don't have any table_a records where status=0 应该选择ID 3,因为没有关联的table_a记录,对于同一标准的另一种观点是:应该选择ID 3,因为没有任何table_a记录,其中status = 0

EDIT Answer - 编辑答案-

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 )

OLD answer - 旧答案-

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

This portion of the original post is not clear: if a Table_B record hasn't any associated Table_A also should be selected. 原始帖子的这一部分内容不清楚: if a Table_B record hasn't any associated Table_A also should be selected. .

If you only want rows from Table_B then: 如果只需要来自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
                )

If you want rows from Table_ B where either there are no rows in Table_A_has_B for a given id_B or where if there are rows it must be associated with a Table_A item where status is 1, then : 如果要从Table_ B行,或者给定id_B Table_A_has_B中没有行,或者必须将行与status为1的Table_A项目相关联,则:

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
                    )

If what you want is rows from Table_A but only where the status is 1 and for all others a null, then the first query I provided would be the solution. 如果您要的是Table_A中的行,但仅状态为1的行,而对于所有其他行,则为空,那么我提供的第一个查询就是解决方案。 Providing us with some expected output results would obviously help tremendously. 为我们提供一些预期的输出结果显然会极大地帮助您。

Edit given update to OP 编辑给定的OP更新

Given your update, which only now makes it clear what you are actually trying to achieve, you do the following: 有了您的更新(现在只能使您清楚地知道要实现的目标),您可以执行以下操作:

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
                    )

By rephrasing your requirement statement to select table_B which does not have associated table_A with status <> 1. I come to the following query statement: 通过改写您的需求语句以选择不具有状态<> 1关联的table_A的table_B,我进入以下查询语句:

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

or 要么

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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