Почему вторичный INNER JOIN ограничивает результаты - PullRequest
0 голосов
/ 12 декабря 2018

Если у меня есть три таблицы, например:

Родители

| id  | title    |
| --- | -------- |
| 1   | Parent 1 |
| 2   | Parent 2 |

Отношения

| parent_id | child_id |
| --------- | -------- |
| 1         | 1        |

Дети

| id  | title   |
| --- | ------- |
| 1   | Child 1 |

И я запускаю следующий запрос:

SELECT parents.title, 
       relationships.child_id 
FROM   parents 
       LEFT JOIN relationships 
              ON parents.id = relationships.parent_id 
       INNER JOIN children 
               ON relationships.child_id = children.id;

Почему он возвращает следующее?

| title    | child_id |
| -------- | -------- |
| Parent 1 | 1        |

Я быожидайте, что он вернет всех родителей (поскольку у родителей LEFT JOIN), и вернет отношения только в том случае, если ребенок существует (поскольку там INNER JOIN).

Скрипка

Ответы [ 4 ]

0 голосов
/ 12 декабря 2018

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

SELECT parents.title, 
   relationships.child_id 
FROM   parents 
   LEFT JOIN (relationships 
              INNER JOIN children 
                  ON relationships.child_id = children.id)
       ON parents.id = relationships.parent_id 

Обратите внимание, что предложение ON для LEFT JOIN перемещено в конец.

0 голосов
/ 12 декабря 2018

Это ваш запрос:

SELECT p.title, r.child_id 
FROM parents p LEFT JOIN
     relationships r
     ON p.id = r.parent_id INNER JOIN
     children c
     ON r.child_id = c.id;
--------^

Первый LEFT JOIN может не найти подходящих отношений для данного родителя.Когда это происходит, r.child_id равно NULL.Очевидно, что для INNER JOIN нет соответствия, поэтому строка отфильтровывается.

Именно поэтому LEFT JOIN s обычно связаны в цепочку.Если у вас есть один, вы продолжаете с дополнительными:

SELECT p.title, r.child_id 
FROM parents p LEFT JOIN
     relationships r
     ON p.id = r.parent_id LEFT JOIN
     children c
     ON r.child_id = c.id;
0 голосов
/ 12 декабря 2018

Ваш inner join находится на детском столе.Попробуйте, используя outer join, он вернет всех родителей.

0 голосов
/ 12 декабря 2018

Это правда, что у вас есть LEFT JOIN relationships в вашем запросе, но у вас также есть INNER JOIN children, который в конечном итоге предотвращает выбор несовпадающих строк.

Попробуйте вместо этого:

SELECT parents.title, 
       relationships.child_id 
FROM   parents 
       LEFT JOIN relationships 
              ON parents.id = relationships.parent_id 
       LEFT JOIN children 
               ON relationships.child_id = children.id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...