Можете ли вы объединить три таблицы с одним и тем же ключом, если этот ключ может отсутствовать в одной или нескольких таблицах? - PullRequest
2 голосов
/ 14 февраля 2020

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

Например, есть TableA, TableB и TableC, каждый из которых содержит только один столбец (мы просто назовем столбцы colA, colB и colC). Значение 10 присутствует в TableA и TableC, но не TableB.

SELECT * FROM TableA FULL OUTER JOIN TableB ON TableA.colA = TableB.colB 
                     FULL OUTER JOIN TableC ON TableB.colB = TableC.colC;

+--------+  +--------+  +--------+
|  colA  |  |  colB  |  |  colC  |
+--------+  +--------+  +--------+
|      5 |  |      5 |  |      5 |
|     10 |  |     15 |  |     10 |
|     15 |  +--------+  |     15 |
+--------+              +--------+

В приведенном выше примере я получаю что-то подобное после объединений:

+--------+--------+--------+
|  colA  |  colB  |  colC  |
+--------+--------+--------+
| 5      | 5      | 5      |
| null   | null   | 10     |
| 15     | 15     | 15     |
| 10     | null   | null   |
+--------+--------+--------+

Мой ожидаемый результат таков:

+--------+--------+--------+
|  colA  |  colB  |  colC  |
+--------+--------+--------+
|      5 | 5      |      5 |
|     10 | null   |     10 |
|     15 | 15     |     15 |
+--------+--------+--------+

Логика c для моего соединения - сначала объединить TableA и TableB, а затем объединить результат с TableC. В этом конкретном сценарии c объединение не работает. Объединение может попытаться сопоставить столбец, переданный из TableA, или столбец из TableB, но я не уверен, как сделать так, чтобы он проверял оба.

Поскольку я впервые присоединился к TableA и TableB, не было соответствующего значения в TableB. Когда я пытаюсь присоединиться к TableC на TableB, он также не находит соответствия, даже если ключ существует в TableA.

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

SELECT * FROM TableA FULL OUTER JOIN TableB ON TableA.colA = TableB.colB 
                     RIGHT OUTER JOIN TableC ON TableC.colC IN (TableA.colA, TableB.colB);

+------+  +------+  +------+     +------+------+------+
| colA |  | colB |  | colC |     | colA | colB | colC |
+------+  +------+  +------+     +------+------+------+
|    5 |  |    5 |  |    5 |     | 5    | 5    |    5 |
|   10 |  |   15 |  |   10 | --> | 10   | null |   10 |
|   15 |  |   25 |  |   15 |     | 15   | 15   |   15 |
+------+  +------+  |   20 |     | null | null |   20 |
                    +------+     +------+------+------+

Ожидаемый результат:

+------+------+------+
| colA | colB | colC |
+------+------+------+
| 5    | 5    | 5    |
| 10   | null | 10   |
| 15   | 15   | 15   |
| null | null | 20   |
| null | 25   | null |
+------+------+------+

К сожалению, сюда не входят значения, которые only существуют в TableA или TableB в финале присоединился к столу, поэтому я использовал FULL OUTER JOIN в первую очередь. С FULL OUTER JOIN я не могу использовать предложение IN. Есть ли решение, которое дает мне то, что я хочу?

DB Fiddle: https://www.db-fiddle.com/f/faMLh4EAAKfBotXbaDofaQ/1

Ответы [ 3 ]

2 голосов
/ 15 февраля 2020

Вот версия, которая демонстрирует полностью трехстороннее полное внешнее соединение. Успешный запрос вернет семь строк:

+------+  +------+  +------+     +------+------+------+
| colA |  | colB |  | colC |     | colA | colB | colC |
+------+  +------+  +------+     +------+------+------+
|    1 |  |    2 |  |    4 |     |    1 | null | null |
|    3 |  |    3 |  |    5 | --> | null |    2 | null |
|    5 |  |    6 |  |    6 |     |    3 |    3 | null |
|    7 |  |    7 |  |    7 |     | null | null |    4 |
+------+  +------+  +------+     |    5 | null |    5 |
                                 | null |    6 |    6 |
                                 |    7 |    7 |    7 |
                                 +------+------+------+
select ColA, ColB, ColC
  from TableA
  full join TableB
    on ColA=ColB
  full join TableC
    on ColC=coalesce(ColA, ColB)
order by coalesce(ColA, ColB, ColC);

Секрет заключается в coalesce ключах предыдущей таблицы в условии соединения каждой дополнительной таблицы.

Вы можете видеть это в действии здесь

0 голосов
/ 14 февраля 2020

Эта комбинация объединений даст вам желаемые результаты:

select * 
from (SELECT * 
      FROM TableC
      full outer join TableB on TableC.colC = TableB.colB ) t1
left join TableA on t1.colc = TableA.colA or  t1.colB = TableA.colA

Вот демоверсия

Это было другое объединение, в котором вы нуждались. Вот еще один пример:

select * from 
(SELECT * 
FROM TableC
full outer join TableB on TableC.colC = TableB.colB ) t1
full join TableA on t1.colc = TableA.colA

Вот демоверсия

0 голосов
/ 14 февраля 2020

Я думаю, что вы хотите left join s:

SELECT *
FROM TableA LEFT OUTER JOIN
     TableB
     ON TableA.colA = TableB.colB LEFT JOIN
     TableC
     ON TableA.colA = TableC.colC;

Вот это скрипка .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...