Можно ли отфильтровать в левом соединении? - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть три таблицы: клиенты, счета и счета. Я бы хотел, чтобы всегда был клиент, и, если у него есть счета, только те счета, которые можно изменить. Я пытаюсь что-то подобное:

select * from Clients
left join Bills on Bills.IDClient = Clients.IDClient
left join BillsStates on BillsStates.IDBillState = Bills.IDState
and BillsStates.AllowModify = 1

Проблема в том, что я получаю все счета клиента, независимо от того, могут ли они быть изменены или нет.

Я пытался с правильным соединением, но в этом случае я не получил никакого результата.

Возможно ли это с помощью объединений или мне нужен какой-то подзапрос? Я бы предпочел решение с объединениями, но если нет способа сделать это таким образом, я бы принял другое решение.

Ответы [ 5 ]

0 голосов
/ 13 сентября 2018

Вместо объединения в подзапросе вы также можете изменить порядок соединений

SELECT c.*, b.*, bs.* -- Todo: only the relevant columns
FROM Bills b
JOIN BillsStates bs ON BillsStates.IDBillState = Bills.IDState
RIGHT JOIN Clients c ON b.IDClient = c.IDClient
0 голосов
/ 13 сентября 2018

вы можете попробовать это.

select * from Clients
    left join 
        ( select * from Bills 
            inner join BillsStates on BillsStates.IDBillState = Bills.IDState
                and BillsStates.AllowModify = 1
        ) B ON  B.IDClient = Clients.IDClient
0 голосов
/ 13 сентября 2018
select * from Clients
left join Bills
    inner join BillsStates on BillsStates.IDBillState = Bills.IDState
on Bills.IDClient = Clients.IDClient
and BillsStates.AllowModify = 1

Проблема, с которой вы столкнулись, заключается в том, что вы исключаете только запись BillsStates, поскольку ваш фильтр находится только в состоянии соединения.Вместо этого вы можете изменить порядок и переместить его в состояние соединения Bills.

0 голосов
/ 13 сентября 2018

Ваш запрос просто заменяет BillsStates.* нулевыми значениями, когда условие BillsStates.AllowModify = 1 не выполняется:

| IDClient | Name | IDClient | IDState | Name   | IDBillState | AllowModify |
|----------|------|----------|---------|--------|-------------|-------------|
| 1        | John | 1        | 1       | Bill 1 | NULL        | NULL        |
| 1        | John | 1        | 2       | Bill 2 | 2           | 1           |
| 2        | Jane | NULL     | NULL    | NULL   | NULL        | NULL        |

Переставьте тип и условие объединения, чтобы получить желаемый результат:

SELECT *
FROM Clients
LEFT JOIN (Bills
INNER JOIN BillsStates ON BillsStates.IDBillState = Bills.IDState) ON Bills.IDClient = Clients.IDClient AND BillsStates.AllowModify = 1;
| IDClient | Name | IDClient | IDState | Name   | IDBillState | AllowModify |
|----------|------|----------|---------|--------|-------------|-------------|
| 1        | John | 1        | 2       | Bill 2 | 2           | 1           |
| 2        | Jane | NULL     | NULL    | NULL   | NULL        | NULL        |
0 голосов
/ 13 сентября 2018

использовать внутреннее объединение между счетами и BillsStates вместо левого соединения и делать левое соединение с клиентом

select c.* from Clients c
left join Bills b on b.IDClient = c.IDClient
inner join BillsStates bs 
on bs.IDBillState = b.IDState  and   b.AllowModify = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...