首页 > 解决方案 > 如何同时加入和联合

问题描述

我确信这有一个简单的解决方案,但我很难找到它。

我有两张桌子

CREATE TABLE t1 (
  "name" VARCHAR(1),
  "id" INTEGER,
  "data1" VARCHAR(2)
);

INSERT INTO t1
  ("name", "id", "data1")
VALUES
  ('a', '1', 'a1'),
  ('d', '1', 'd1');
  
  

CREATE TABLE t2 (
  "name" VARCHAR(1),
  "id" INTEGER,
  "data2" VARCHAR(2)
);

INSERT INTO t2
  ("name", "id", "data2")
VALUES
  ('d', '1', 'd2'),
  ('k', '1', 'k2');

我想要这个最终的组合表:

| name | id  | data1 | data2 |
| ---- | --- | ----- | ----- |
| a    | 1   | a1    |       |
| d    | 1   | d1    | d2    |
| k    | 1   |       | k2    |

我尝试过的事情:

做一个工会

select 
  t1.name,
  t1.id,
  t1.data1,
  NULL as data2
from t1
union 
select 
  t2.name,
  t2.id,
  NULL as data1,
  t2.data2
from t2

| name | id  | data1 | data2 |
| ---- | --- | ----- | ----- |
| a    | 1   | a1    |       |
| d    | 1   | d1    |       |
| d    | 1   |       | d2    |
| k    | 1   |       | k2    |

做一个完整的加入

select * from t1
full join t2 on t2.id = t1.id 
     and t2.name = t1.name;

| name | id  | data1 | name | id  | data2 |
| ---- | --- | ----- | ---- | --- | ----- |
| a    | 1   | a1    |      |     |       |
| d    | 1   | d1    | d    | 1   | d2    |
|      |     |       | k    | 1   | k2    |

答案介于两者之间

标签: sqlpostgresql

解决方案


谢谢,戈登和尼克的回答。

我检查了文档,发现了一个更短的变体:

select * 
from t1 
natural full join t2;

文档

此外,JOIN USING抑制冗余列的输出:不需要打印两个匹配的列,因为它们必须具有相同的值。虽然JOIN ON从 T1 生成所有列,然后从 T2 生成所有列,JOIN USING但为每个列出的列对(按列出的顺序)生成一个输出列,然后是 T1 中的任何剩余列,然后是 T2 中的任何剩余列。


推荐阅读