SQL-запрос для получения ожидаемого результата - PullRequest
2 голосов
/ 18 февраля 2011

Это моя схема БД.

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|
+----+
  • Идентификатор 1 не должен быть выбран, так как одна из его записей table_a имеетstatus = 0
  • Идентификаторы 2 и 4 должны быть выбраны, потому что все его записи table_a имеют статус = 1
  • Идентификатор 3 должен быть выбран, потому что не связано с записями table_a, другая точка зрениядля того же критерия: Id 3 должен быть выбран, потому что нет никаких записей table_a, где статус = 0

Ответы [ 3 ]

3 голосов
/ 18 февраля 2011

РЕДАКТИРОВАТЬ Ответ -

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
2 голосов
/ 18 февраля 2011
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, тогда:

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
                    )
0 голосов
/ 18 февраля 2011

Перефразируя ваше заявление с требованием, чтобы выбрать table_B, который не связан с table_A со статусом <> 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...