Sql 我有3个表,需要独占左连接

Sql 我有3个表,需要独占左连接,sql,postgresql,join,Sql,Postgresql,Join,表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,因为我的第一个表实际上是一个复

表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
,因为我的第一个表实际上是一个复杂的查询,我希望避免重新计算它


如果没有
联合所有人,我不确定这是否有效。例如,此处的所有答案()
用它工作

因此,我的解决方案是:


编辑:找到一种方法,使用:


我将使用
union all
,它比join和clear更快,为什么不使用它呢

ID | Val1 | Val2 :- | ---: | ---: A | 4 |空 A |空| 7 B |空| 8 B | 5 |空 B | 6 |空 C | 7 |空 C |空| 9 dbfiddle刚刚尝试了以下操作:

得到:

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

想知道其他人的意见。

@k06a添加了一种不使用Union的可能方法。任何人都知道如何避免不使用DISTINCT的重复行。
的重复行。参见我的第二个解决方案:分组集就是原则上做到这一点的功能。@S-Man谢谢,你的想法引导我找到了这个解决方案,这帮助我将请求时间从12分钟提高到6秒:)我的第一个表实际上是一个复杂的查询,我希望避免重新计算。
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
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 | null A | null | 7 B | null | 8 B | 5 | null B | 6 | null C | 7 | null C | null | 9
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  |  _