0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

UNIONは複数のSELECT結果を縦に結合する構文です。似た構文のUNION ALLとの違いや、他の集合演算子(INTERSECT, EXCEPT)も含めて整理します。

この後の流れ

  1. UNIONの基本
  2. UNIONとUNION ALLの違い(重要)
  3. UNIONを使うための3条件
  4. 応用:異なるテーブルの統合レポート
  5. INTERSECT/EXCEPTとの比較
  6. まとめ

1. UNIONの基本

複数のSELECT結果を縦方向に結合し、1つの結果セットにします。

SELECT customer_name, email FROM customers_tokyo
UNION
SELECT customer_name, email FROM customers_osaka;

2. UNIONとUNION ALLの違い(重要)

項目 UNION UNION ALL
重複行 自動的に除去する 除去せずそのまま結合
内部処理 重複排除のためソート/ハッシュ処理が走る 単純結合のみ
パフォーマンス 重複排除のコストがかかり遅い 高速
-- 重複を許容してよい・パフォーマンス重視なら基本UNION ALL
SELECT product_id FROM sales_2025
UNION ALL
SELECT product_id FROM sales_2026;

実務での鉄則: 重複除去が明確に必要な場合以外は、原則UNION ALLを使うべきです。「なんとなくUNION」を使うと、意図しない重複排除コストと、意図しないデータ欠落(本来重複ではない行が誤って同一視される等)のリスクがあります。

3. UNIONを使うための3条件

条件 内容
① 列数の一致 各SELECTの列数が同じであること
② データ型の互換性 対応する列同士のデータ型に互換性があること
③ 列名は最初のSELECTに従う 出力の列名は1つ目のSELECT文の列名が採用される
-- OK例:型は違っても暗黙変換できる範囲ならOK
SELECT employee_id, hire_date::text AS date_info FROM employees
UNION ALL
SELECT order_id, memo FROM orders;

4. 応用:異なるテーブルの統合レポート

ケース: 「顧客」と「見込み客」という別テーブルを、種別ラベル付きで1つの連絡先リストにまとめたい。

SELECT
    name,
    email,
    '既存顧客' AS contact_type
FROM customers

UNION ALL

SELECT
    name,
    email,
    '見込み客' AS contact_type
FROM leads

ORDER BY contact_type, name;

固定文字列リテラル('既存顧客')を列として混ぜることで、統合後もデータの出所を区別できます。ORDER BYはUNION全体の最後に一度だけ書きます(各SELECTには付けられません)。

5. INTERSECT/EXCEPTとの比較

UNION以外にも集合演算子があります。

演算子 意味 イメージ(集合論)
UNION 両方の和集合(重複除去) A ∪ B
UNION ALL 両方の和(重複含む) A + B(多重集合)
INTERSECT 両方に共通する行のみ A ∩ B
EXCEPT Aに存在してBに存在しない行 A − B
-- 今月と先月の両方で購入した顧客(共通)
SELECT customer_id FROM orders_this_month
INTERSECT
SELECT customer_id FROM orders_last_month;

-- 今月だけ購入して先月は購入していない顧客(新規/離脱把握)
SELECT customer_id FROM orders_this_month
EXCEPT
SELECT customer_id FROM orders_last_month;

注意: PostgreSQLはINTERSECT/EXCEPTをサポートしますが、MySQLは8.0.31以降でINTERSECT/EXCEPTに対応(それ以前はサブクエリ/EXISTSで代替が必要)という違いがあるため、DB移行時は要確認です。

6. まとめ

目的 使う構文
重複を除いて縦結合したい UNION
高速に縦結合したい(重複OK) UNION ALL
両方に共通する行だけ欲しい INTERSECT
片方にしかない行だけ欲しい EXCEPT

さいごに

UNION系はパフォーマンス影響が大きい構文なので、「本当に重複排除が必要か」を都度考える癖をつけると良いクエリが書けます。次回はPostgreSQLのストアドプロシージャです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?