`FULL JOIN` 和 `UNION ALL`

萌哥-爱学习發表於2024-09-12

在 SQL 中,`FULL JOIN` 和 `UNION ALL` 是兩種不同的操作,它們的結果也有顯著的區別。

### FULL JOIN
`FULL JOIN`(全外連線)會返回兩張表中所有的記錄。對於沒有匹配的記錄,結果中會用 `NULL` 填充缺失的部分。具體來說:

- 如果表 A 和表 B 中有匹配的記錄,這些記錄會合並在一起。
- 如果表 A 中有記錄在表 B 中沒有匹配,結果中會顯示這些記錄,表 B 的欄位會用 `NULL` 填充。
- 如果表 B 中有記錄在表 A 中沒有匹配,結果中會顯示這些記錄,表 A 的欄位會用 `NULL` 填充。

### UNION ALL
`UNION ALL` 會將兩張表的所有記錄合併在一起,包括重複的記錄。它不會去除重複項,也不會進行任何匹配。具體來說:

- 表 A 的所有記錄會被列出。
- 表 B 的所有記錄會被列出。
- 如果表 A 和表 B 中有相同的記錄,它們會在結果中重複出現。

### 舉例說明
假設有以下兩張表:

**表 A**
| id | name |
|----|-------|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |

**表 B**
| id | age |
|----|-----|
| 2 | 30 |
| 3 | 25 |
| 4 | 40 |

- 使用 `FULL JOIN` 的結果:

| id | name | age |
|----|--------|------|
| 1 | Alice | NULL |
| 2 | Bob | 30 |
| 3 | Charlie| 25 |
| 4 | NULL | 40 |

- 使用 `UNION ALL` 的結果:

| id | name | age |
|----|--------|------|
| 1 | Alice | NULL |
| 2 | Bob | NULL |
| 3 | Charlie| NULL |
| NULL | NULL | 30 |
| NULL | NULL | 25 |
| NULL | NULL | 40 |

### 總結
- `FULL JOIN` 關注的是兩張表的匹配和缺失記錄,結果中會合並相關欄位。
- `UNION ALL` 只是簡單地將兩張表的記錄疊加在一起,不考慮匹配關係。

希望這個解釋能幫助你理解這兩者之間的區別!


在 Hive 中,雖然沒有直接的 `FULL JOIN` 語法,但可以透過組合 `LEFT JOIN` 和 `RIGHT JOIN` 來實現類似的效果。下面是一個示例,展示如何在 Hive 中建立兩張表,並使用 `FULL JOIN` 和 `UNION ALL` 來結合它們的結果。

### 建立表

```sql
CREATE TABLE TableA (
id INT,
name STRING
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE;

CREATE TABLE TableB (
id INT,
age INT
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE;
```

### 插入資料

```sql
-- 插入 TableA 的資料
INSERT INTO TABLE TableA VALUES
(1, 'Alice'),
(2, 'Bob'),
(3, 'Charlie'),
(4, 'David'),
(5, 'Eva');

-- 插入 TableB 的資料
INSERT INTO TABLE TableB VALUES
(2, 30),
(3, 25),
(4, 40),
(6, 28),
(7, 22);

### 使用 FULL JOIN 的實現

在 Hive 中,可以透過 `LEFT JOIN` 和 `RIGHT JOIN` 來模擬 `FULL JOIN`:

```sql
-- FULL JOIN 的實現
SELECT
A.id AS A_id,
A.name,
B.id AS B_id,
B.age
FROM
TableA A
LEFT JOIN
TableB B ON A.id = B.id

UNION ALL

SELECT
A.id AS A_id,
A.name,
B.id AS B_id,
B.age
FROM
TableA A
RIGHT JOIN
TableB B ON A.id = B.id
WHERE
A.id IS NULL; -- 只選擇 TableB 中沒有匹配的記錄
```

### 使用 UNION ALL

使用 `UNION ALL` 來合併兩張表的所有記錄:

```sql
SELECT
id,
name,

FROM
TableA

UNION ALL

SELECT
id,

age
FROM
TableB;
```

### 結果示例

1. **FULL JOIN 的結果**(模擬):

| A_id | name | B_id | age |
|------|---------|------|-----|
| 1 | Alice | NULL | NULL|
| 2 | Bob | 2 | 30 |
| 3 | Charlie | 3 | 25 |
| 4 | David | 4 | 40 |
| 5 | Eva | NULL | NULL|
| NULL | NULL | 6 | 28 |
| NULL | NULL | 7 | 22 |

2. **UNION ALL 的結果**:

| id | name | age |
|-----|---------|-----|
| 1 | Alice | NULL|
| 2 | Bob | NULL|
| 3 | Charlie | NULL|
| 4 | David | NULL|
| 5 | Eva | NULL|
| 2 | NULL | 30 |
| 3 | NULL | 25 |
| 4 | NULL | 40 |
| 6 | NULL | 28 |
| 7 | NULL | 22 |

### 總結

- 在 Hive 中,使用 `LEFT JOIN` 和 `RIGHT JOIN` 的組合來模擬 `FULL JOIN`。
- `UNION ALL` 將兩張表的記錄簡單地合併在一起,不考慮匹配關係。

希望這個示例能幫助你理解如何在 Hive 中使用 `FULL JOIN` 和 `UNION ALL`!如果有其他問題,請隨時問我。

相關文章