> ## Documentation Index
> Fetch the complete documentation index at: https://villagesql.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MySQL の UNION

> UNION が 2 つの MySQL クエリの行を 1 つの結果に積み重ねる仕組み、UNION ALL との違い、および 2 つのクエリが本当に守らなければならない 1 つの規則。

> [card] [VillageSQL is a drop-in replacement for MySQL with extensions.](https://villagesql.com/docs/en/8.4/stable/install-server.md)
>
> All examples on this page work on VillageSQL. Install Now →

結合はテーブルを横に並べ、結果を広げます。`UNION` は結果を縦に積み重ね、
結果を長くします。2 つのクエリが同じ形の行を生成し、それらを 1 つのリストに
したいときに使います。

始める前に、`mysql -u root -p sakila` でクライアントを開いてください。

## UNION の仕組み

```sql theme={null}
SELECT COLUMN_LIST FROM FIRST_TABLE
UNION
SELECT COLUMN_LIST FROM SECOND_TABLE;
```

各 `COLUMN_LIST` を欲しい列に、`FIRST_TABLE` と `SECOND_TABLE` を読むテーブルに
置き換えます。

2 つのクエリは同じ数の列を返さなければならず、サーバーはそれらの列を名前では
なく位置で対応付けます。

`UNION` は重複行を取り除きます。`UNION ALL` は重複行を保持し、何も比較する
必要がないため高速です。

## 例

### UNION は重複を取り除く

ここでは両方の部分が同じクエリなので、2 番目のすべての行は 1 番目のいずれかの
行の重複です。

```sql theme={null}
SELECT rating FROM film UNION SELECT rating FROM film;
```

```text theme={null}
+--------+
| rating |
+--------+
| PG     |
| G      |
| NC-17  |
| PG-13  |
| R      |
+--------+
5 rows in set (0.00 sec)
```

2,000 行から 5 行です。`UNION` は結合した結果を 1 回の処理で重複排除するため、
一方の部分の内側での繰り返しも、両部分にまたがる繰り返しと同じ扱いになります。
答えは、同じ列に対する [SELECT DISTINCT](https://villagesql.com/docs/ja/tutorial/select-distinct.md) と
一致します。

### UNION ALL は重複を保持する

```sql theme={null}
SELECT rating FROM film UNION ALL SELECT rating FROM film;
```

```text theme={null}
+--------+
| rating |
+--------+
| PG     |
| G      |
| NC-17  |
...
+--------+
2000 rows in set (0.00 sec)
```

両方の部分のすべての行です。重複がないと分かっているとき、または重複こそが
目的であるときは、常に `UNION ALL` を使ってください。

### 異なるテーブルの行を積み重ねる

これこそが `UNION` の本来の用途です。同じ種類のものを保持する 2 つの
テーブルです。リテラルの列が、各行がどちらの部分から来たかを示します。

```sql theme={null}
SELECT 'staff' AS source, first_name, last_name FROM staff
UNION ALL
SELECT 'actor', first_name, last_name FROM actor WHERE actor_id <= 3;
```

```text theme={null}
+--------+------------+-----------+
| source | first_name | last_name |
+--------+------------+-----------+
| staff  | Mike       | Hillyer   |
| staff  | Jon        | Stephens  |
| actor  | PENELOPE   | GUINESS   |
| actor  | NICK       | WAHLBERG  |
| actor  | ED         | CHASE     |
+--------+------------+-----------+
5 rows in set (0.00 sec)
```

2 番目のクエリはリテラルにエイリアスを付けていません。その必要はありません。
列の見出しは 1 番目のクエリだけから来るためです。

## UNION は順序を約束しない

どちらの部分も、まとまって届くことも、先に届くことも保証されません。サーバーは
プランが生成した順序のまま行を返すため、2 つの同一のクエリの `UNION ALL` は
交互に混ざることがあります。末尾の `ORDER BY` が順序を固定する唯一の方法で、
これは [LIMIT](https://villagesql.com/docs/ja/tutorial/limit.md) や [GROUP BY](https://villagesql.com/docs/ja/tutorial/group-by.md) の場合と
同じです。

## 各部分の列数は同じでなければならない

```sql theme={null}
SELECT first_name FROM actor UNION SELECT first_name, last_name FROM actor;
```

```text theme={null}
ERROR 1222 (21000): The used SELECT statements have a different number of columns
```

列名は一致する必要はありません。厳密なのは列数だけで、何かが実行される前に
チェックされます。

## ORDER BY は結果全体に適用される

末尾の `ORDER BY` は、最後のクエリではなく、結合された行を並べ替えます。1 番目の
部分のエイリアスを指定してください。それが結果の列の名前だからです。

```sql theme={null}
SELECT first_name AS name FROM staff
UNION
SELECT last_name FROM staff
ORDER BY name;
```

```text theme={null}
+----------+
| name     |
+----------+
| Hillyer  |
| Jon      |
| Mike     |
| Stephens |
+----------+
4 rows in set (0.00 sec)
```

一方の部分だけを並べ替えたり制限したりするには、その部分をかっこで包み、その
`ORDER BY` と `LIMIT` をかっこの中に置きます。

## まとめ

* 2 つのクエリの行を 1 つの結果に積み重ねるには `UNION` を使います。
* `UNION` は重複を取り除き、`UNION ALL` は重複を保持すると考えてください。
* 重複がないと分かっているときは `UNION ALL` を優先します。行う作業が少ないためです。
* 両方の部分の列数を同じにします。そうでなければ `ERROR 1222` になります。
* 見出しは 1 番目のクエリから来て、末尾の `ORDER BY` がすべてを並べ替えると考えてください。

## 関連項目

* [SELECT DISTINCT](https://villagesql.com/docs/ja/tutorial/select-distinct.md) — 1 つのクエリから重複を取り除く
* [結合の仕組み](https://villagesql.com/docs/ja/tutorial/joins.md) — 代わりにテーブルを横に並べて結合する
* [サブクエリ](https://villagesql.com/docs/ja/tutorial/subqueries.md) — 積み重ねるのではなく値として使うクエリ


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.