SQL: полное внешнее соединение или союз или нет? - PullRequest
0 голосов
/ 10 апреля 2020

У меня есть таблица A_to_ C, которая является таблицей соединения многих ко многим между A и C

╔═══════╦══════════╗
║ a_col ║  c_col   ║
╠═══════╬══════════╣
║ a     ║ x        ║
║ b     ║ y        ║
║ c     ║ z        ║
╚═══════╩══════════╝

У меня также есть таблица B_to_ C, которая является множеством многие объединяют таблицы из B и C

╔═══════╦═══════╗
║ b_col ║ c_col ║
╠═══════╬═══════╣
║ g     ║ u     ║
║ h     ║ v     ║
║ i     ║ w     ║
╚═══════╩═══════╝

Я хочу добиться результата, подобного этому:

╔═══════╦═══════╦═══════╗
║ a_col ║ c_col ║ b_col ║
╠═══════╬═══════╬═══════╣
║ a     ║ x     ║ NULL  ║
║ b     ║ y     ║ NULL  ║
║ c     ║ z     ║ NULL  ║
║ NULL  ║ u     ║ g     ║
║ NULL  ║ v     ║ h     ║
║ NULL  ║ w     ║ i     ║
╚═══════╩═══════╩═══════╝

Я понятия не имею, могу ли я использовать объединения, потому что x, y, z значения в A_to_ C не могут быть сопоставлены со значениями u, v, w в B_to_ C

Я не могу использовать объединения, потому что мне нужны отдельные столбцы a_col и b_col или я могу?

Возможно, мне не известна конструкция SQL, которая может достичь желаемого результата.

В качестве бонуса я хочу преобразовать столбцы в результатах как:

╔═══════╦═══════╦════════╗
║ a_col ║ c_col ║ b_col  ║
╠═══════╬═══════╬════════╣
║ true  ║ x     ║ false  ║
║ true  ║ y     ║ false  ║
║ true  ║ z     ║ false  ║
║ false ║ u     ║ true   ║
║ false ║ v     ║ true   ║
║ false ║ w     ║ true   ║
╚═══════╩═══════╩════════╝

ТИА!

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

I думаю, вы можете использовать для этого LEFT OUTER JOIN с.

SELECT a.a_col, c.c_col, b.b_col
FROM C c
LEFT OUTER JOIN A_to_C a ON c.c_col = a.c_col
LEFT OUTER JOIN B_to_C b ON c.c_col = b.c_col
WHERE a.a_col IS NOT NULL OR b.b_col IS NOT NULL;

Предложение WHERE является необязательным, если вы можете гарантировать, что все значения в c имеют соответствующее значение в a или b или в обоих.

Для запроса бонуса измените SELECT на

SELECT a.a_col IS NOT NULL AS a_col,
    c.c_col,
    b.b_col IS NOT NULL AS b_col

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

Кстати, в зависимости от вашего варианта использования, если значение в c может быть в ОБА a и b, использование JOIN s даст вам одну строку для этого значения c, при использовании UNION ALL вы получите две строки: одну с NULL в a и одну с NULL в b. Я не знаю, какой из них более эффективен для больших столов.

1 голос
/ 10 апреля 2020

Вы можете использовать UNION ALL:

select a_col, c_col, null b_col
from A_to_C
union all
select null, c_col, b_col
from B_to_C

и для другого запроса:

select 
  (t.a_col is not null) a_col, 
  t.c_col, 
  (t.b_col is not null) b_col
from (
  select a_col, c_col, null b_col
  from A_to_C
  union all
  select null, c_col, b_col
  from B_to_C
) t

Или установить логические значения непосредственно в связанных запросах:

select true a_col, c_col, false b_col
from A_to_C
union all
select false a_col, c_col, true b_col
from B_to_C

См. Демоверсию . Результаты:

> a_col | c_col | b_col
> :---- | :---- | :----
> a     | x     | null 
> b     | y     | null 
> c     | z     | null 
> null  | u     | g    
> null  | v     | h    
> null  | w     | i 

и

> a_col | c_col | b_col
> :---- | :---- | :----
> t     | x     | f    
> t     | y     | f    
> t     | z     | f    
> f     | u     | t    
> f     | v     | t    
> f     | w     | t 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...