У меня 3 стола и мне нужно эксклюзивное левое соединение - PullRequest
0 голосов
/ 01 ноября 2019

Таблица_1:

A
B
C

Таблица_2:

A | 4
B | 5
B | 6
C | 7

Таблица_3:

A | 7
B | 8
C | 9

Используя 2 левых соединения, я получил это:

A | 4 | 7
B | 5 | 8
B | 6 | 8
C | 7 | 9

Но я делаю группы по первому столбцу, и 8 накапливается дважды, я хочу получить:

A | 4 | _
A | _ | 7
B | 5 | _
B | _ | 8
B | 6 | _
C | 7 | _
C | _ | 9

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

https://dbfiddle.uk/?rdbms=postgres_12&fiddle=d6012e281e3ba43487b1bfec85fd886c

Ответы [ 3 ]

2 голосов
/ 01 ноября 2019

Я буду использовать union all, это быстрее, чем соединение и ясно, почему бы не использовать его?

CREATE TABLE Table1
  ("ID" varchar(1), "Val" int)
;

INSERT INTO Table1
  ("ID", "Val")
VALUES
  ('A', 4),
  ('B', 5),
  ('B', 6),
  ('C', 7)
;
CREATE TABLE Table2
  ("ID" varchar(1), "Val" int)
;

INSERT INTO Table2
  ("ID", "Val")
VALUES
  ('A', 7),
  ('B', 8),
  ('C', 9)
;
select "ID","Val" as "Val1",null as "Val2" from Table1
union all
select "ID",null as "Val1","Val" as "Val2" from Table2
order by "ID"
ID | Val1 | Val2
:- | ---: | ---:
A  |    4 | <em>null</em>
A  | <em>null</em> |    7
B  | <em>null</em> |    8
B  |    5 | <em>null</em>
B  |    6 | <em>null</em>
C  |    7 | <em>null</em>
C  | <em>null</em> |    9

дБ <> скрипка здесь

2 голосов
/ 01 ноября 2019

Я не уверен, что это работает без UNION ALL. Например, все ответы здесь ( SQL слева объединяет две таблицы независимо ) работают с ним.

Итак, мое решение:

demo: db <>fiddle

SELECT
    a.id,
    b.val,
    NULL
FROM
    a
LEFT JOIN b ON a.id = b.id

UNION ALL

SELECT
    a.id,
    NULL,
    c.val
FROM
    a
LEFT JOIN c ON a.id = c.id

ORDER BY 1,2,3

Редактировать: Нашел способ, используя GROUPING SETS:

демо: db <> fiddle

SELECT
    ab.*,
    c.val
FROM (
    SELECT
        a.id,
        b.val
    FROM a
    LEFT JOIN b ON a.id = b.id
    GROUP BY GROUPING SETS ((a.id), (a.id, b.val))
) ab
LEFT JOIN c ON ab.id = c.id AND ab.val IS NULL
0 голосов
/ 01 ноября 2019

Только что попробовал следующее https://dbfiddle.uk/?rdbms=postgres_12&fiddle=cd0121bafe1bde6738bb8afc9a9f1970:

SELECT DISTINCT a.id, t1.val, t2.val
FROM a
LEFT JOIN (SELECT b.id, b.val FROM b UNION ALL SELECT b.id, NULL FROM b) t1 on a.id = t1.id
LEFT JOIN (SELECT c.id, c.val FROM c UNION ALL SELECT c.id, NULL FROM c) t2 on a.id = t2.id and t1.val is null
WHERE t1.val IS NOT NULL
   OR t2.val IS NOT NULL

И получил:

B  |  6  |  _
B  |  _  |  8
A  |  _  |  7
A  |  4  |  _
B  |  5  |  _
C  |  _  |  9
C  |  7  |  _

Хочу узнать мнение других.

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