<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://mochiu.net/index.php?action=history&amp;feed=atom&amp;title=MySQL_-_UNION</id>
	<title>MySQL - UNION - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://mochiu.net/index.php?action=history&amp;feed=atom&amp;title=MySQL_-_UNION"/>
	<link rel="alternate" type="text/html" href="https://mochiu.net/index.php?title=MySQL_-_UNION&amp;action=history"/>
	<updated>2026-04-21T11:27:56Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://mochiu.net/index.php?title=MySQL_-_UNION&amp;diff=14267&amp;oldid=prev</id>
		<title>Wiki: ページの作成:「== 概要 == UNION演算子は、2つ以上のSELECT文の結果を結合して、単一の結果セットを返すセット演算子である。&lt;br&gt; &lt;br&gt; &lt;code&gt;UNION&lt;/code&gt; はデフォルトで重複行を削除し、&lt;code&gt;UNION ALL&lt;/code&gt; は重複行を含めて全ての行を返す。&lt;br&gt; 複数のテーブルや条件から取得したデータを1つの結果セットにまとめる際に有用である。&lt;br&gt; &lt;br&gt; MySQL 8.0.31以降では、&lt;code&gt;INTERSECT&lt;/…」</title>
		<link rel="alternate" type="text/html" href="https://mochiu.net/index.php?title=MySQL_-_UNION&amp;diff=14267&amp;oldid=prev"/>
		<updated>2026-02-08T03:55:03Z</updated>

		<summary type="html">&lt;p&gt;ページの作成:「== 概要 == UNION演算子は、2つ以上のSELECT文の結果を結合して、単一の結果セットを返すセット演算子である。&amp;lt;br&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;UNION&amp;lt;/code&amp;gt; はデフォルトで重複行を削除し、&amp;lt;code&amp;gt;UNION ALL&amp;lt;/code&amp;gt; は重複行を含めて全ての行を返す。&amp;lt;br&amp;gt; 複数のテーブルや条件から取得したデータを1つの結果セットにまとめる際に有用である。&amp;lt;br&amp;gt; &amp;lt;br&amp;gt; MySQL 8.0.31以降では、&amp;lt;code&amp;gt;INTERSECT&amp;lt;/…」&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== 概要 ==&lt;br /&gt;
UNION演算子は、2つ以上のSELECT文の結果を結合して、単一の結果セットを返すセット演算子である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;UNION&amp;lt;/code&amp;gt; はデフォルトで重複行を削除し、&amp;lt;code&amp;gt;UNION ALL&amp;lt;/code&amp;gt; は重複行を含めて全ての行を返す。&amp;lt;br&amp;gt;&lt;br /&gt;
複数のテーブルや条件から取得したデータを1つの結果セットにまとめる際に有用である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
MySQL 8.0.31以降では、&amp;lt;code&amp;gt;INTERSECT&amp;lt;/code&amp;gt; (交差) と &amp;lt;code&amp;gt;EXCEPT&amp;lt;/code&amp;gt; (差集合) 演算子も使用可能になり、セット演算の機能が大幅に拡張された。&amp;lt;br&amp;gt;&lt;br /&gt;
これらの演算子は、SQL標準に準拠した集合演算を提供する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
UNIONを使用する時は、各SELECT文の列数を一致させる必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
列名は最初のSELECT文のものが使用され、データ型は自動的に互換性のある型に変換される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
パフォーマンスの観点では、&amp;lt;code&amp;gt;UNION ALL&amp;lt;/code&amp;gt; は重複排除の処理が不要なため、&amp;lt;code&amp;gt;UNION&amp;lt;/code&amp;gt; より高速である。&amp;lt;br&amp;gt;&lt;br /&gt;
大規模なデータセットでは、&amp;lt;code&amp;gt;UNION ALL&amp;lt;/code&amp;gt; の方が2〜3倍高速になることもある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt; と &amp;lt;code&amp;gt;LIMIT&amp;lt;/code&amp;gt; を組み合わせることにより、結果セット全体のソートや行数の制限が可能である。&amp;lt;br&amp;gt;&lt;br /&gt;
個別の &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt; 文にも &amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt; と &amp;lt;code&amp;gt;LIMIT&amp;lt;/code&amp;gt; を適用できるが、その場合は括弧で囲む必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UNION演算子 ==&lt;br /&gt;
==== 基本構文 ====&lt;br /&gt;
UNIONは、2つ以上のSELECT文の結果を結合する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 基本構文&lt;br /&gt;
 SELECT column1, column2 FROM table1&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT column1, column2 FROM table2;&lt;br /&gt;
 &lt;br /&gt;
 # UNION ALL (重複を含める)&lt;br /&gt;
 SELECT column1, column2 FROM table1&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT column1, column2 FROM table2;&lt;br /&gt;
 &lt;br /&gt;
 # 3つ以上のSELECT文を結合&lt;br /&gt;
 SELECT column1 FROM table1&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT column1 FROM table2&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT column1 FROM table3;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
UNIONの基本的なルールを以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ UNIONの注意点&lt;br /&gt;
! 項目 !! 説明&lt;br /&gt;
|-&lt;br /&gt;
| 列数の一致 || 各 &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt; 文の列数は一致する必要がある。&lt;br /&gt;
|-&lt;br /&gt;
| 列名 || 結果セットの列名は、最初の &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt; 文のものが使用される。&lt;br /&gt;
|-&lt;br /&gt;
| データ型 || 各列のデータ型は互換性がある必要がある。型強制ルールに従って自動変換される。&lt;br /&gt;
|-&lt;br /&gt;
| 重複の扱い || &amp;lt;code&amp;gt;UNION&amp;lt;/code&amp;gt; は重複行を削除し、&amp;lt;code&amp;gt;UNION ALL&amp;lt;/code&amp;gt; は重複を保持する。&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 複数テーブルから従業員名を取得&lt;br /&gt;
 SELECT name FROM employees&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT name FROM contractors;&lt;br /&gt;
 &lt;br /&gt;
 # 重複を含めて取得&lt;br /&gt;
 SELECT name FROM employees&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT name FROM contractors;&lt;br /&gt;
 &lt;br /&gt;
 # 異なる条件で同じテーブルから取得&lt;br /&gt;
 SELECT product_name, price FROM products WHERE category_id = 1&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT product_name, price FROM products WHERE category_id = 2;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== UNION vs UNION ALL ====&lt;br /&gt;
&amp;lt;code&amp;gt;UNION&amp;lt;/code&amp;gt; と &amp;lt;code&amp;gt;UNION ALL&amp;lt;/code&amp;gt; の違いは、重複行の扱いである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ UNIONとUNION ALLの比較&lt;br /&gt;
! 項目 !! UNION !! UNION ALL&lt;br /&gt;
|-&lt;br /&gt;
| 重複行の扱い || 重複行を削除 (DISTINCT) || 重複行を含めて全ての行を返す&lt;br /&gt;
|-&lt;br /&gt;
| 一時テーブル || インデックス付き一時テーブルを作成 || 一時テーブル不要&lt;br /&gt;
|-&lt;br /&gt;
| パフォーマンス || 重複排除のため遅い || 高速 (大規模データで2-3倍)&lt;br /&gt;
|-&lt;br /&gt;
| 使用場面 || 重複を排除したい場合 || 全ての行が必要な場合&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # UNION (重複削除)&lt;br /&gt;
 SELECT &amp;#039;A&amp;#039; AS col UNION SELECT &amp;#039;A&amp;#039; AS col;&lt;br /&gt;
 # 結果: 1行 (&amp;#039;A&amp;#039;)&lt;br /&gt;
 &lt;br /&gt;
 # UNION ALL (重複保持)&lt;br /&gt;
 SELECT &amp;#039;A&amp;#039; AS col UNION ALL SELECT &amp;#039;A&amp;#039; AS col;&lt;br /&gt;
 # 結果: 2行 (&amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;)&lt;br /&gt;
 &lt;br /&gt;
 # パフォーマンス比較例&lt;br /&gt;
 # 遅い (重複排除処理が必要)&lt;br /&gt;
 SELECT user_id FROM orders WHERE status = &amp;#039;completed&amp;#039;&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT user_id FROM orders WHERE status = &amp;#039;shipped&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 # 高速 (重複排除なし)&lt;br /&gt;
 SELECT user_id FROM orders WHERE status = &amp;#039;completed&amp;#039;&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT user_id FROM orders WHERE status = &amp;#039;shipped&amp;#039;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
重複が存在しないことが明らかな場合は、&amp;lt;code&amp;gt;UNION ALL&amp;lt;/code&amp;gt; を使用することでパフォーマンスを向上できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 異なるテーブルからの結合 (重複なし)&lt;br /&gt;
 SELECT id, &amp;#039;employee&amp;#039; AS type FROM employees&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT id, &amp;#039;contractor&amp;#039; AS type FROM contractors;&lt;br /&gt;
 &lt;br /&gt;
 # 異なる条件での結合 (重複なし)&lt;br /&gt;
 SELECT product_id FROM orders WHERE created_at &amp;lt; &amp;#039;2024-01-01&amp;#039;&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT product_id FROM orders WHERE created_at &amp;gt;= &amp;#039;2024-01-01&amp;#039;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 列数とデータ型 ====&lt;br /&gt;
UNIONを使用する時は、各SELECT文の列数を一致させる必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
列数が一致しない場合は、エラーが発生する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # エラーになる例 (列数が一致しない)&lt;br /&gt;
 SELECT name, age FROM users&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT name FROM employees;&lt;br /&gt;
 # ERROR 1222 (21000): The used SELECT statements have a different number of columns&lt;br /&gt;
 &lt;br /&gt;
 # 正しい形式 (列数を一致させる)&lt;br /&gt;
 SELECT name, age FROM users&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT name, NULL AS age FROM employees;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
データ型は、互換性のある型である必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
型が異なる場合は、MySQLの型強制ルールに従って自動的に変換される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 数値型と文字列型の結合 (文字列型に変換される)&lt;br /&gt;
 SELECT id FROM users&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT &amp;#039;admin&amp;#039; AS id;&lt;br /&gt;
 &lt;br /&gt;
 # 異なる数値型の結合 (精度の高い型に変換される)&lt;br /&gt;
 SELECT price FROM products  # DECIMAL型&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT discount FROM coupons;  # FLOAT型&lt;br /&gt;
 # 結果: DOUBLE型&lt;br /&gt;
 &lt;br /&gt;
 # 日付型と文字列型の結合&lt;br /&gt;
 SELECT created_at FROM orders  # DATETIME型&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT &amp;#039;2024-01-01&amp;#039; AS created_at;  # 文字列&lt;br /&gt;
 # 結果: 文字列型&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
列名は、最初のSELECT文のものが使用される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 列名の例&lt;br /&gt;
 SELECT name AS employee_name FROM employees&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT name AS contractor_name FROM contractors;&lt;br /&gt;
 # 結果の列名: employee_name&lt;br /&gt;
 &lt;br /&gt;
 # 列名を明示的に指定&lt;br /&gt;
 SELECT name FROM employees&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT full_name FROM contractors;&lt;br /&gt;
 # 結果の列名: name&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INTERSECT演算子 (MySQL 8.0.31以降) ==&lt;br /&gt;
==== 基本構文 ====&lt;br /&gt;
&amp;lt;code&amp;gt;INTERSECT&amp;lt;/code&amp;gt; は、2つ以上のSELECT文の結果の共通行のみを返す。(交差)&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
MySQL 8.0.31以降で使用可能である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 基本構文&lt;br /&gt;
 SELECT column1, column2 FROM table1&lt;br /&gt;
 INTERSECT&lt;br /&gt;
 SELECT column1, column2 FROM table2;&lt;br /&gt;
 &lt;br /&gt;
 # INTERSECT DISTINCT (デフォルト、重複削除)&lt;br /&gt;
 SELECT column1 FROM table1&lt;br /&gt;
 INTERSECT DISTINCT&lt;br /&gt;
 SELECT column1 FROM table2;&lt;br /&gt;
 &lt;br /&gt;
 # INTERSECT ALL (重複保持)&lt;br /&gt;
 SELECT column1 FROM table1&lt;br /&gt;
 INTERSECT ALL&lt;br /&gt;
 SELECT column1 FROM table2;&lt;br /&gt;
 &lt;br /&gt;
 # 3つ以上のSELECT文の交差&lt;br /&gt;
 SELECT column1 FROM table1&lt;br /&gt;
 INTERSECT&lt;br /&gt;
 SELECT column1 FROM table2&lt;br /&gt;
 INTERSECT&lt;br /&gt;
 SELECT column1 FROM table3;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;INTERSECT&amp;lt;/code&amp;gt; は、両方の結果セットに存在する行のみを返す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 両方の注文に含まれる商品を取得&lt;br /&gt;
 SELECT product_id FROM orders WHERE user_id = 1&lt;br /&gt;
 INTERSECT&lt;br /&gt;
 SELECT product_id FROM orders WHERE user_id = 2;&lt;br /&gt;
 &lt;br /&gt;
 # 従業員と管理者の両方に含まれるユーザ&lt;br /&gt;
 SELECT user_id FROM employees&lt;br /&gt;
 INTERSECT&lt;br /&gt;
 SELECT user_id FROM managers;&lt;br /&gt;
 &lt;br /&gt;
 # 両方のカテゴリに属する商品&lt;br /&gt;
 SELECT product_id FROM product_categories WHERE category_id = 1&lt;br /&gt;
 INTERSECT&lt;br /&gt;
 SELECT product_id FROM product_categories WHERE category_id = 2;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== INTERSECT DISTINCTとINTERSECT ALL ====&lt;br /&gt;
&amp;lt;code&amp;gt;INTERSECT DISTINCT&amp;lt;/code&amp;gt; (デフォルト) は重複を削除し、&amp;lt;code&amp;gt;INTERSECT ALL&amp;lt;/code&amp;gt; は重複を保持する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # INTERSECT DISTINCT (重複削除)&lt;br /&gt;
 SELECT value FROM table1  # &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;B&amp;#039;&lt;br /&gt;
 INTERSECT DISTINCT&lt;br /&gt;
 SELECT value FROM table2;  # &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;C&amp;#039;&lt;br /&gt;
 # 結果: &amp;#039;A&amp;#039; (1行)&lt;br /&gt;
 &lt;br /&gt;
 # INTERSECT ALL (重複保持)&lt;br /&gt;
 SELECT value FROM table1  # &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;B&amp;#039;&lt;br /&gt;
 INTERSECT ALL&lt;br /&gt;
 SELECT value FROM table2;  # &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;C&amp;#039;&lt;br /&gt;
 # 結果: &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039; (2行)&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;INTERSECT ALL&amp;lt;/code&amp;gt; では、各値の出現回数の最小値が結果に含まれる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 出現回数の例&lt;br /&gt;
 SELECT value FROM table1  # &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;B&amp;#039;&lt;br /&gt;
 INTERSECT ALL&lt;br /&gt;
 SELECT value FROM table2;  # &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;C&amp;#039;&lt;br /&gt;
 # 結果: &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039; (table1に3回、table2に2回 → 最小値2回)&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 可換性と演算子優先順位 ====&lt;br /&gt;
&amp;lt;code&amp;gt;INTERSECT&amp;lt;/code&amp;gt; は可換性がある。(順序を入れ替えても結果は同じ)&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # これらは同じ結果&lt;br /&gt;
 SELECT col FROM table1 INTERSECT SELECT col FROM table2;&lt;br /&gt;
 SELECT col FROM table2 INTERSECT SELECT col FROM table1;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
セット演算子の優先順位は以下の通りである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ セット演算子の優先順位&lt;br /&gt;
! 優先順位 !! 演算子&lt;br /&gt;
|-&lt;br /&gt;
| 高 || &amp;lt;code&amp;gt;INTERSECT&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 低 || &amp;lt;code&amp;gt;UNION&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;EXCEPT&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # INTERSECTが先に評価される&lt;br /&gt;
 SELECT col FROM table1&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT col FROM table2&lt;br /&gt;
 INTERSECT&lt;br /&gt;
 SELECT col FROM table3;&lt;br /&gt;
 # (table2 INTERSECT table3) が先に評価され、その後 table1 と UNION される&lt;br /&gt;
 &lt;br /&gt;
 # 括弧で優先順位を明示&lt;br /&gt;
 (SELECT col FROM table1 UNION SELECT col FROM table2)&lt;br /&gt;
 INTERSECT&lt;br /&gt;
 SELECT col FROM table3;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== MySQL 8.0.31以前の代替方法 ====&lt;br /&gt;
MySQL 8.0.31以前では、&amp;lt;code&amp;gt;INNER JOIN&amp;lt;/code&amp;gt; または &amp;lt;code&amp;gt;EXISTS&amp;lt;/code&amp;gt; を使用して INTERSECTを代替できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # INTERSECTの代替 (INNER JOIN)&lt;br /&gt;
 SELECT DISTINCT t1.col&lt;br /&gt;
    FROM table1 t1&lt;br /&gt;
    INNER JOIN table2 t2 ON t1.col = t2.col;&lt;br /&gt;
 &lt;br /&gt;
 # INTERSECTの代替 (EXISTS)&lt;br /&gt;
 SELECT DISTINCT col FROM table1 t1&lt;br /&gt;
    WHERE EXISTS (SELECT 1 FROM table2 t2 WHERE t2.col = t1.col);&lt;br /&gt;
 &lt;br /&gt;
 # INTERSECT ALLの代替 (より複雑)&lt;br /&gt;
 SELECT t1.col&lt;br /&gt;
    FROM table1 t1&lt;br /&gt;
    INNER JOIN (&lt;br /&gt;
       SELECT col, COUNT(*) AS cnt FROM table2 GROUP BY col&lt;br /&gt;
    ) t2 ON t1.col = t2.col&lt;br /&gt;
    WHERE (&lt;br /&gt;
       SELECT COUNT(*) FROM table1 t1_inner&lt;br /&gt;
          WHERE t1_inner.col = t1.col AND t1_inner.rowid &amp;lt;= t1.rowid&lt;br /&gt;
    ) &amp;lt;= t2.cnt;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== EXCEPT演算子 (MySQL 8.0.31以降) ==&lt;br /&gt;
==== 基本構文 ====&lt;br /&gt;
&amp;lt;code&amp;gt;EXCEPT&amp;lt;/code&amp;gt; は、第1のSELECT結果から第2のSELECT結果を除外する。(差集合)&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
MySQL 8.0.31以降で使用可能である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 基本構文&lt;br /&gt;
 SELECT column1, column2 FROM table1&lt;br /&gt;
 EXCEPT&lt;br /&gt;
 SELECT column1, column2 FROM table2;&lt;br /&gt;
 &lt;br /&gt;
 # EXCEPT DISTINCT (デフォルト、重複削除)&lt;br /&gt;
 SELECT column1 FROM table1&lt;br /&gt;
 EXCEPT DISTINCT&lt;br /&gt;
 SELECT column1 FROM table2;&lt;br /&gt;
 &lt;br /&gt;
 # EXCEPT ALL (重複保持)&lt;br /&gt;
 SELECT column1 FROM table1&lt;br /&gt;
 EXCEPT ALL&lt;br /&gt;
 SELECT column1 FROM table2;&lt;br /&gt;
 &lt;br /&gt;
 # 複数のEXCEPT&lt;br /&gt;
 SELECT column1 FROM table1&lt;br /&gt;
 EXCEPT&lt;br /&gt;
 SELECT column1 FROM table2&lt;br /&gt;
 EXCEPT&lt;br /&gt;
 SELECT column1 FROM table3;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;EXCEPT&amp;lt;/code&amp;gt; は、第1の結果セットから第2の結果セットに含まれる行を除外する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # ユーザ1が注文した商品のうち、ユーザ2が注文していない商品&lt;br /&gt;
 SELECT product_id FROM orders WHERE user_id = 1&lt;br /&gt;
 EXCEPT&lt;br /&gt;
 SELECT product_id FROM orders WHERE user_id = 2;&lt;br /&gt;
 &lt;br /&gt;
 # 全従業員から管理者を除外&lt;br /&gt;
 SELECT user_id FROM employees&lt;br /&gt;
 EXCEPT&lt;br /&gt;
 SELECT user_id FROM managers;&lt;br /&gt;
 &lt;br /&gt;
 # 全商品から注文済み商品を除外 (在庫のみ)&lt;br /&gt;
 SELECT product_id FROM products&lt;br /&gt;
 EXCEPT&lt;br /&gt;
 SELECT product_id FROM order_items;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== EXCEPT DISTINCTとEXCEPT ALL ====&lt;br /&gt;
&amp;lt;code&amp;gt;EXCEPT DISTINCT&amp;lt;/code&amp;gt; (デフォルト) は重複を削除し、&amp;lt;code&amp;gt;EXCEPT ALL&amp;lt;/code&amp;gt; は重複を保持する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # EXCEPT DISTINCT (重複削除)&lt;br /&gt;
 SELECT value FROM table1  # &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;B&amp;#039;, &amp;#039;C&amp;#039;&lt;br /&gt;
 EXCEPT DISTINCT&lt;br /&gt;
 SELECT value FROM table2;  # &amp;#039;A&amp;#039;, &amp;#039;D&amp;#039;&lt;br /&gt;
 # 結果: &amp;#039;B&amp;#039;, &amp;#039;C&amp;#039; (重複削除)&lt;br /&gt;
 &lt;br /&gt;
 # EXCEPT ALL (重複保持)&lt;br /&gt;
 SELECT value FROM table1  # &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;B&amp;#039;, &amp;#039;C&amp;#039;&lt;br /&gt;
 EXCEPT ALL&lt;br /&gt;
 SELECT value FROM table2;  # &amp;#039;A&amp;#039;, &amp;#039;D&amp;#039;&lt;br /&gt;
 # 結果: &amp;#039;A&amp;#039;, &amp;#039;B&amp;#039;, &amp;#039;C&amp;#039; (table1の2つの&amp;#039;A&amp;#039;から、table2の1つの&amp;#039;A&amp;#039;を除外 → 1つの&amp;#039;A&amp;#039;が残る)&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;EXCEPT ALL&amp;lt;/code&amp;gt; では、table1の出現回数からtable2の出現回数を引いた回数が結果に含まれる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 出現回数の例&lt;br /&gt;
 SELECT value FROM table1  # &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;B&amp;#039;&lt;br /&gt;
 EXCEPT ALL&lt;br /&gt;
 SELECT value FROM table2;  # &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;C&amp;#039;&lt;br /&gt;
 # 結果: &amp;#039;A&amp;#039;, &amp;#039;B&amp;#039; (table1の3つの&amp;#039;A&amp;#039;から、table2の2つの&amp;#039;A&amp;#039;を除外 → 1つの&amp;#039;A&amp;#039;が残る)&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 非可換性 ====&lt;br /&gt;
EXCEPTは非可換である。(順序を入れ替えると結果が異なる)&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # A EXCEPT B&lt;br /&gt;
 SELECT col FROM table1 EXCEPT SELECT col FROM table2;&lt;br /&gt;
 # table1にあり、table2にない行&lt;br /&gt;
 &lt;br /&gt;
 # B EXCEPT A&lt;br /&gt;
 SELECT col FROM table2 EXCEPT SELECT col FROM table1;&lt;br /&gt;
 # table2にあり、table1にない行&lt;br /&gt;
 &lt;br /&gt;
 # これらは異なる結果&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== MySQL 8.0.31以前の代替方法 ====&lt;br /&gt;
MySQL 8.0.31以前では、&amp;lt;code&amp;gt;LEFT JOIN WHERE IS NULL&amp;lt;/code&amp;gt; または &amp;lt;code&amp;gt;NOT EXISTS&amp;lt;/code&amp;gt; を使用して、EXCEPTを代替できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # EXCEPTの代替 (LEFT JOIN WHERE IS NULL)&lt;br /&gt;
 SELECT DISTINCT t1.col&lt;br /&gt;
    FROM table1 t1&lt;br /&gt;
    LEFT JOIN table2 t2 ON t1.col = t2.col&lt;br /&gt;
    WHERE t2.col IS NULL;&lt;br /&gt;
 &lt;br /&gt;
 # EXCEPTの代替 (NOT EXISTS)&lt;br /&gt;
 SELECT DISTINCT col FROM table1 t1&lt;br /&gt;
    WHERE NOT EXISTS (SELECT 1 FROM table2 t2 WHERE t2.col = t1.col);&lt;br /&gt;
 &lt;br /&gt;
 # EXCEPT ALLの代替 (より複雑)&lt;br /&gt;
 SELECT t1.col&lt;br /&gt;
    FROM table1 t1&lt;br /&gt;
    LEFT JOIN (&lt;br /&gt;
       SELECT col, COUNT(*) AS cnt FROM table2 GROUP BY col&lt;br /&gt;
    ) t2 ON t1.col = t2.col&lt;br /&gt;
    WHERE (&lt;br /&gt;
       SELECT COUNT(*) FROM table1 t1_inner&lt;br /&gt;
          WHERE t1_inner.col = t1.col AND t1_inner.rowid &amp;lt;= t1.rowid&lt;br /&gt;
    ) &amp;gt; COALESCE(t2.cnt, 0);&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ORDER BYとLIMITの組み合わせ ==&lt;br /&gt;
==== 全体に対するORDER BYとLIMIT ====&lt;br /&gt;
&amp;lt;code&amp;gt;UNION&amp;lt;/code&amp;gt; の結果全体をソートしたり、行数を制限したりする場合は、最後のセット演算子の後に &amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt; や &amp;lt;code&amp;gt;LIMIT&amp;lt;/code&amp;gt; を指定する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 全体をソート&lt;br /&gt;
 SELECT name, age FROM employees&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT name, age FROM contractors&lt;br /&gt;
 ORDER BY age DESC;&lt;br /&gt;
 &lt;br /&gt;
 # 全体を制限&lt;br /&gt;
 SELECT product_id FROM orders WHERE user_id = 1&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT product_id FROM orders WHERE user_id = 2&lt;br /&gt;
 LIMIT 10;&lt;br /&gt;
 &lt;br /&gt;
 # ソートと制限の組み合わせ&lt;br /&gt;
 SELECT name, salary FROM employees WHERE department_id = 1&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT name, salary FROM employees WHERE department_id = 2&lt;br /&gt;
 ORDER BY salary DESC&lt;br /&gt;
 LIMIT 5;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
ORDER BYで指定する列名は、最初のSELECT文の列名を使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 列名の指定&lt;br /&gt;
 SELECT name AS employee_name, salary FROM employees&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT full_name AS contractor_name, rate FROM contractors&lt;br /&gt;
 ORDER BY employee_name;  # 最初のSELECTの列名を使用&lt;br /&gt;
 &lt;br /&gt;
 # エイリアスなしの場合&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT name, rate FROM contractors&lt;br /&gt;
 ORDER BY name, salary;&lt;br /&gt;
 &lt;br /&gt;
 # 列番号での指定も可能&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT name, rate FROM contractors&lt;br /&gt;
 ORDER BY 2 DESC, 1;  # 2列目 (salary/rate) 降順、1列目 (name) 昇順&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 個別のSELECT文に対するORDER BYとLIMIT ====&lt;br /&gt;
個別のSELECT文に &amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt; や &amp;lt;code&amp;gt;LIMIT&amp;lt;/code&amp;gt; を適用する場合は、丸括弧 &amp;lt;code&amp;gt;()&amp;lt;/code&amp;gt; で囲む必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 個別のSELECT文に対してLIMITを適用&lt;br /&gt;
 (SELECT name, salary FROM employees ORDER BY salary DESC LIMIT 5)&lt;br /&gt;
 UNION&lt;br /&gt;
 (SELECT name, salary FROM contractors ORDER BY salary DESC LIMIT 5);&lt;br /&gt;
 # 各テーブルから上位5件を取得し、結合&lt;br /&gt;
 &lt;br /&gt;
 # 個別のSELECT文に対してORDER BYとLIMITを適用&lt;br /&gt;
 (SELECT product_name, price FROM products WHERE category_id = 1 ORDER BY price DESC LIMIT 3)&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 (SELECT product_name, price FROM products WHERE category_id = 2 ORDER BY price DESC LIMIT 3);&lt;br /&gt;
 &lt;br /&gt;
 # 条件付きで上位を取得&lt;br /&gt;
 (SELECT user_id, SUM(amount) AS total FROM orders WHERE status = &amp;#039;completed&amp;#039; GROUP BY user_id ORDER BY total DESC LIMIT 10)&lt;br /&gt;
 UNION&lt;br /&gt;
 (SELECT user_id, SUM(amount) AS total FROM orders WHERE status = &amp;#039;pending&amp;#039; GROUP BY user_id ORDER BY total DESC LIMIT 10);&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
丸括弧 &amp;lt;code&amp;gt;()&amp;lt;/code&amp;gt; で囲まない場合、&amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt; と &amp;lt;code&amp;gt;LIMIT&amp;lt;/code&amp;gt; は全体に適用される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 括弧なし (全体に適用)&lt;br /&gt;
 SELECT name FROM employees&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT name FROM contractors&lt;br /&gt;
 ORDER BY name&lt;br /&gt;
 LIMIT 10;&lt;br /&gt;
 # UNION の結果全体を name でソートし、10件に制限&lt;br /&gt;
 &lt;br /&gt;
 # 括弧あり (個別に適用)&lt;br /&gt;
 (SELECT name FROM employees ORDER BY name LIMIT 10)&lt;br /&gt;
 UNION&lt;br /&gt;
 (SELECT name FROM contractors ORDER BY name LIMIT 10);&lt;br /&gt;
 # 各SELECTで10件ずつ取得し、結合 (最大20件)&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 注意事項 ====&lt;br /&gt;
括弧内と外の両方に &amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt; や &amp;lt;code&amp;gt;LIMIT&amp;lt;/code&amp;gt; がある場合、結果が未定義になる可能性がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 未定義の動作 (推奨しない)&lt;br /&gt;
 (SELECT name FROM employees ORDER BY name LIMIT 10)&lt;br /&gt;
 UNION&lt;br /&gt;
 (SELECT name FROM contractors ORDER BY name LIMIT 10)&lt;br /&gt;
 ORDER BY name&lt;br /&gt;
 LIMIT 5;&lt;br /&gt;
 # 各SELECTのORDER BYは無視される可能性がある&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
個別のSELECT文において、ORDER BYを使用する場合は、&amp;lt;code&amp;gt;LIMIT&amp;lt;/code&amp;gt; と組み合わせる必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;LIMIT&amp;lt;/code&amp;gt; がない場合、ORDER BYは無視される可能性がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # ORDER BYが無視される可能性がある&lt;br /&gt;
 (SELECT name FROM employees ORDER BY name)&lt;br /&gt;
 UNION&lt;br /&gt;
 (SELECT name FROM contractors);&lt;br /&gt;
 &lt;br /&gt;
 # LIMITと組み合わせると有効&lt;br /&gt;
 (SELECT name FROM employees ORDER BY name LIMIT 100)&lt;br /&gt;
 UNION&lt;br /&gt;
 (SELECT name FROM contractors);&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== サンプルクエリ ==&lt;br /&gt;
==== 複数テーブルのデータ統合 ====&lt;br /&gt;
異なるテーブルから同じ形式のデータを取得して統合する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 従業員と契約社員のリストを統合&lt;br /&gt;
 SELECT id, name, &amp;#039;employee&amp;#039; AS type, hire_date AS start_date FROM employees&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT id, name, &amp;#039;contractor&amp;#039; AS type, contract_start FROM contractors&lt;br /&gt;
 ORDER BY start_date DESC;&lt;br /&gt;
 &lt;br /&gt;
 # 複数の注文テーブルを統合&lt;br /&gt;
 SELECT order_id, user_id, amount, created_at FROM orders_2023&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT order_id, user_id, amount, created_at FROM orders_2024&lt;br /&gt;
 ORDER BY created_at DESC;&lt;br /&gt;
 &lt;br /&gt;
 # ログテーブルの統合&lt;br /&gt;
 SELECT log_id, message, &amp;#039;info&amp;#039; AS level, created_at FROM info_logs&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT log_id, message, &amp;#039;error&amp;#039; AS level, created_at FROM error_logs&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT log_id, message, &amp;#039;warning&amp;#039; AS level, created_at FROM warning_logs&lt;br /&gt;
 ORDER BY created_at DESC;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== FULL OUTER JOINの代替 ====&lt;br /&gt;
MySQLにはFULL OUTER JOINが存在しないため、&amp;lt;code&amp;gt;LEFT JOIN&amp;lt;/code&amp;gt; と &amp;lt;code&amp;gt;RIGHT JOIN&amp;lt;/code&amp;gt; を &amp;lt;code&amp;gt;UNION&amp;lt;/code&amp;gt; で結合することで代替できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # FULL OUTER JOINの代替&lt;br /&gt;
 SELECT u.user_id, u.name, o.order_id&lt;br /&gt;
    FROM users u&lt;br /&gt;
    LEFT JOIN orders o ON u.user_id = o.user_id&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT u.user_id, u.name, o.order_id&lt;br /&gt;
    FROM users u&lt;br /&gt;
    RIGHT JOIN orders o ON u.user_id = o.user_id;&lt;br /&gt;
 &lt;br /&gt;
 # FULL OUTER JOINの代替 (重複削除なし)&lt;br /&gt;
 SELECT e.employee_id, e.name, d.department_name&lt;br /&gt;
    FROM employees e&lt;br /&gt;
    LEFT JOIN departments d ON e.department_id = d.id&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT e.employee_id, e.name, d.department_name&lt;br /&gt;
    FROM employees e&lt;br /&gt;
    RIGHT JOIN departments d ON e.department_id = d.id&lt;br /&gt;
    WHERE e.employee_id IS NULL;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 条件付き統合 ====&lt;br /&gt;
異なる条件でデータを取得し、優先度ラベルを付与して統合する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 優先度ラベル付与&lt;br /&gt;
 SELECT task_id, title, &amp;#039;high&amp;#039; AS priority FROM tasks WHERE priority_score &amp;gt; 80&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT task_id, title, &amp;#039;medium&amp;#039; AS priority FROM tasks WHERE priority_score BETWEEN 50 AND 80&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT task_id, title, &amp;#039;low&amp;#039; AS priority FROM tasks WHERE priority_score &amp;lt; 50&lt;br /&gt;
 ORDER BY priority_score DESC;&lt;br /&gt;
 &lt;br /&gt;
 # ステータス別の集計&lt;br /&gt;
 SELECT &amp;#039;completed&amp;#039; AS status, COUNT(*) AS count FROM orders WHERE status = &amp;#039;completed&amp;#039;&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT &amp;#039;pending&amp;#039; AS status, COUNT(*) AS count FROM orders WHERE status = &amp;#039;pending&amp;#039;&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT &amp;#039;cancelled&amp;#039; AS status, COUNT(*) AS count FROM orders WHERE status = &amp;#039;cancelled&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 # 期間別のデータ統合&lt;br /&gt;
 SELECT product_id, SUM(amount) AS total, &amp;#039;Q1&amp;#039; AS quarter&lt;br /&gt;
    FROM sales WHERE QUARTER(sale_date) = 1&lt;br /&gt;
    GROUP BY product_id&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT product_id, SUM(amount) AS total, &amp;#039;Q2&amp;#039; AS quarter&lt;br /&gt;
    FROM sales WHERE QUARTER(sale_date) = 2&lt;br /&gt;
    GROUP BY product_id&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT product_id, SUM(amount) AS total, &amp;#039;Q3&amp;#039; AS quarter&lt;br /&gt;
    FROM sales WHERE QUARTER(sale_date) = 3&lt;br /&gt;
    GROUP BY product_id&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT product_id, SUM(amount) AS total, &amp;#039;Q4&amp;#039; AS quarter&lt;br /&gt;
    FROM sales WHERE QUARTER(sale_date) = 4&lt;br /&gt;
    GROUP BY product_id&lt;br /&gt;
 ORDER BY product_id, quarter;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 複数のセット演算の組み合わせ ====&lt;br /&gt;
&amp;lt;code&amp;gt;UNION&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;INTERSECT&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;EXCEPT&amp;lt;/code&amp;gt; を組み合わせて複雑な集合演算を行う。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # ユーザ1または2が注文したが、ユーザ3は注文していない商品&lt;br /&gt;
 (SELECT product_id FROM orders WHERE user_id = 1&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT product_id FROM orders WHERE user_id = 2)&lt;br /&gt;
 EXCEPT&lt;br /&gt;
 SELECT product_id FROM orders WHERE user_id = 3;&lt;br /&gt;
 &lt;br /&gt;
 # カテゴリ1と2の両方に属し、かつ在庫がある商品&lt;br /&gt;
 SELECT product_id FROM product_categories WHERE category_id = 1&lt;br /&gt;
 INTERSECT&lt;br /&gt;
 SELECT product_id FROM product_categories WHERE category_id = 2&lt;br /&gt;
 INTERSECT&lt;br /&gt;
 SELECT product_id FROM inventory WHERE stock &amp;gt; 0;&lt;br /&gt;
 &lt;br /&gt;
 # 全従業員から、管理者または退職者を除外&lt;br /&gt;
 SELECT user_id FROM employees&lt;br /&gt;
 EXCEPT&lt;br /&gt;
 (SELECT user_id FROM managers&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT user_id FROM resigned_employees);&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== パフォーマンス最適化 ==&lt;br /&gt;
==== UNIONとUNION ALLのパフォーマンス ====&lt;br /&gt;
&amp;lt;code&amp;gt;UNION&amp;lt;/code&amp;gt; は、重複排除のために内部一時テーブル (インデックス付き) を作成する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;UNION ALL&amp;lt;/code&amp;gt; は、一時テーブルを作成せず、全ての行をそのまま返すため高速である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
大規模なデータセットでは、&amp;lt;code&amp;gt;UNION ALL&amp;lt;/code&amp;gt; の方が2-3倍高速になることがある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 遅い (一時テーブルを作成して重複排除)&lt;br /&gt;
 SELECT user_id FROM orders WHERE status = &amp;#039;completed&amp;#039;&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT user_id FROM orders WHERE status = &amp;#039;shipped&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 # 高速 (一時テーブル不要)&lt;br /&gt;
 SELECT user_id FROM orders WHERE status = &amp;#039;completed&amp;#039;&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT user_id FROM orders WHERE status = &amp;#039;shipped&amp;#039;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
重複が存在しないことが明らかな場合は、&amp;lt;code&amp;gt;UNION ALL&amp;lt;/code&amp;gt; を使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 異なるテーブル (重複なし)&lt;br /&gt;
 SELECT id FROM employees&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT id FROM contractors;&lt;br /&gt;
 &lt;br /&gt;
 # 排他的な条件 (重複なし)&lt;br /&gt;
 SELECT product_id FROM products WHERE category_id = 1&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT product_id FROM products WHERE category_id = 2;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 条件の早期適用 ====&lt;br /&gt;
WHERE句を各SELECT内に配置することにより、不要な行を早期に除外できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 効率的 (各SELECTで条件を適用)&lt;br /&gt;
 SELECT name FROM employees WHERE department_id = 1&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT name FROM employees WHERE department_id = 2;&lt;br /&gt;
 &lt;br /&gt;
 # 非効率 (UNION後にフィルタリング)&lt;br /&gt;
 SELECT name, department_id FROM (&lt;br /&gt;
    SELECT name, department_id FROM employees&lt;br /&gt;
    UNION&lt;br /&gt;
    SELECT name, department_id FROM contractors&lt;br /&gt;
 ) AS combined&lt;br /&gt;
 WHERE department_id IN (1, 2);&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== LIMITの最適化 ====&lt;br /&gt;
個別のSELECT文にLIMITを適用することにより、取得行数を制限できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 効率的 (各SELECTで上位のみ取得)&lt;br /&gt;
 (SELECT name, salary FROM employees ORDER BY salary DESC LIMIT 10)&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 (SELECT name, salary FROM contractors ORDER BY salary DESC LIMIT 10)&lt;br /&gt;
 ORDER BY salary DESC&lt;br /&gt;
 LIMIT 10;&lt;br /&gt;
 &lt;br /&gt;
 # 非効率 (全行を取得してから制限)&lt;br /&gt;
 SELECT name, salary FROM employees&lt;br /&gt;
 UNION ALL&lt;br /&gt;
 SELECT name, salary FROM contractors&lt;br /&gt;
 ORDER BY salary DESC&lt;br /&gt;
 LIMIT 10;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== FOR UPDATEとLOCK IN SHARE MODEの注意事項 ====&lt;br /&gt;
&amp;lt;code&amp;gt;FOR UPDATE&amp;lt;/code&amp;gt; や &amp;lt;code&amp;gt;LOCK IN SHARE MODE&amp;lt;/code&amp;gt; を使用する場合は、個別のSELECT文を括弧で囲む必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 正しい形式 (括弧で囲む)&lt;br /&gt;
 (SELECT id, name FROM employees WHERE department_id = 1 FOR UPDATE)&lt;br /&gt;
 UNION&lt;br /&gt;
 (SELECT id, name FROM employees WHERE department_id = 2 FOR UPDATE);&lt;br /&gt;
 &lt;br /&gt;
 # エラーになる形式 (括弧なし)&lt;br /&gt;
 SELECT id, name FROM employees WHERE department_id = 1&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT id, name FROM employees WHERE department_id = 2&lt;br /&gt;
 FOR UPDATE;&lt;br /&gt;
 # ERROR: Incorrect usage of UNION and FOR UPDATE&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 一時テーブルの監視 ====&lt;br /&gt;
&amp;lt;code&amp;gt;UNION&amp;lt;/code&amp;gt; が内部一時テーブルを作成しているかを確認するには、&amp;lt;code&amp;gt;SHOW STATUS&amp;lt;/code&amp;gt; を使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 一時テーブルの作成状況を確認&lt;br /&gt;
 SHOW STATUS LIKE &amp;#039;Created_tmp%&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 # Created_tmp_disk_tables: ディスク上に作成された一時テーブル数&lt;br /&gt;
 # Created_tmp_tables: メモリ上に作成された一時テーブル数&lt;br /&gt;
 &lt;br /&gt;
 # クエリ実行前にリセット&lt;br /&gt;
 FLUSH STATUS;&lt;br /&gt;
 &lt;br /&gt;
 # クエリ実行&lt;br /&gt;
 SELECT name FROM employees&lt;br /&gt;
 UNION&lt;br /&gt;
 SELECT name FROM contractors;&lt;br /&gt;
 &lt;br /&gt;
 # 一時テーブルの作成数を確認&lt;br /&gt;
 SHOW STATUS LIKE &amp;#039;Created_tmp%&amp;#039;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Created_tmp_disk_tables&amp;lt;/code&amp;gt; が増加している場合は、一時テーブルがディスクに作成されており、パフォーマンスに影響する可能性がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 # 一時テーブルのサイズ制限を確認&lt;br /&gt;
 SHOW VARIABLES LIKE &amp;#039;tmp_table_size&amp;#039;;&lt;br /&gt;
 SHOW VARIABLES LIKE &amp;#039;max_heap_table_size&amp;#039;;&lt;br /&gt;
 &lt;br /&gt;
 # 必要に応じて増やす (セッションレベル)&lt;br /&gt;
 SET SESSION tmp_table_size = 64 * 1024 * 1024;  # 64MB&lt;br /&gt;
 SET SESSION max_heap_table_size = 64 * 1024 * 1024;  # 64MB&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#seo:&lt;br /&gt;
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki&lt;br /&gt;
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,電気回路,電子回路,基板,プリント基板&lt;br /&gt;
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux&lt;br /&gt;
|image=/resources/assets/MochiuLogo_Single_Blue.png&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
__FORCETOC__&lt;br /&gt;
[[カテゴリ:MySQL]]&lt;/div&gt;</summary>
		<author><name>Wiki</name></author>
	</entry>
</feed>