MySQLでは、UNION 句は、複数のクエリの結果を1つの結果セットに結合します。
次のテーブルがあるとします。
SELECT * FROM Teachers;
SELECT * FROM Students; 結果:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 1 | Warren | | 2 | Ben | | 3 | Cathy | | 4 | Cathy | | 5 | Bill | | 6 | Bill | +-----------+-------------+ +-----------+-------------+ | StudentId | StudentName | +-----------+-------------+ | 1 | Faye | | 2 | Jet | | 3 | Spike | | 4 | Ein | | 5 | Warren | | 6 | Bill | +-----------+-------------+
UNIONを挿入できます これら2つのSELECTの間の句 すべての教師と生徒を返すためのステートメント:
SELECT TeacherName FROM Teachers
UNION
SELECT StudentName FROM Students; 結果:
+-------------+ | TeacherName | +-------------+ | Warren | | Ben | | Cathy | | Bill | | Faye | | Jet | | Spike | | Ein | +-------------+
列名は最初のSELECTから取得されます ステートメント。
デフォルトでは、UNION 句は暗黙的にDISTINCTを適用します 手術。つまり、デフォルトでは個別の値のみを返します。したがって、上記の結果には、ウォーレン、キャシー、ビルがそれぞれ1つずつ含まれています。これは、結合されたテーブルに実際に2つのウォーレン、2つのキャシー、および3つのビルが含まれているという事実にもかかわらずです(キャシーと呼ばれる2人の教師、ウォーレンと呼ばれる教師と顧客、およびビルと呼ばれる2人、およびビルと呼ばれる1人の学生がいます)。
DISTINCTを明示的に使用する例を次に示します。 条項:
SELECT TeacherName FROM Teachers
UNION DISTINCT
SELECT StudentName FROM Students; 結果:
+-------------+ | TeacherName | +-------------+ | Warren | | Ben | | Cathy | | Bill | | Faye | | Jet | | Spike | | Ein | +-------------+
したがって、DISTINCTを使用しない場合と同じ結果が得られます。 条項。
ALLを使用できます 結果に重複する値を含めるキーワード:
SELECT TeacherName FROM Teachers
UNION ALL
SELECT StudentName FROM Students; 結果:
+-------------+ | TeacherName | +-------------+ | Warren | | Ben | | Cathy | | Cathy | | Bill | | Bill | | Faye | | Jet | | Spike | | Ein | | Warren | | Bill | +-------------+
今回は、最初の例で取得した8行ではなく、12行を取得しました。
キャシーの両方が返還され、3つの請求書すべてが返還されたことがわかります。
TABLE ステートメント
MySQL 8.0.19から、UNIONを使用できます TABLEを含む句 声明。
次に例を示します:
TABLE Teachers
UNION
TABLE Students; 結果:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 1 | Warren | | 2 | Ben | | 3 | Cathy | | 4 | Cathy | | 5 | Bill | | 6 | Bill | | 1 | Faye | | 2 | Jet | | 3 | Spike | | 4 | Ein | | 5 | Warren | +-----------+-------------+
これは、次のクエリに相当します:
SELECT * FROM Teachers
UNION
SELECT * FROM Students; 結果:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 1 | Warren | | 2 | Ben | | 3 | Cathy | | 4 | Cathy | | 5 | Bill | | 6 | Bill | | 1 | Faye | | 2 | Jet | | 3 | Spike | | 4 | Ein | | 5 | Warren | +-----------+-------------+
これらのステートメントは、前の最初の例よりも多くの行を返すことに気付くでしょう。これは、テーブル内のすべての列を選択しているためです。これにより、以前は重複していた場所に重複がなくなります。たとえば、Billという2人の教師がここに返されますが、前の例では1人だけが返されます。これは、TeacherId 列には異なる値が含まれているため、行は重複していません。
ORDER BYの使用 ユニオンクエリの句
ORDER BYを使用できます 各SELECTの句 ステートメントおよび/または結合されたUNION クエリ。
SELECT ステートメント
ORDER BYを使用する場合 個々のSELECTの句 UNION内のステートメント クエリでは、各SELECTを囲む必要があります 括弧内のステートメント:
(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2); 結果:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 2 | Ben | | 5 | Bill | | 6 | Bill | | 4 | Ein | +-----------+-------------+
これを行う場合、実際には出力の結果が順序付けられないことに注意してください。 LIMITを適用するときに取得する、選択した行のサブセットを決定する目的でのみ結果を並べ替えます。 句。
したがって、ORDER BYを使用します LIMITなし 句は出力に影響を与えません。
UNION クエリ
ORDER BYを使用することもできます クエリ全体の句。これにより、出力全体が一緒に順序付けられます。
この例では、前の例を使用して、結合された結果を並べ替えます。
(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2)
ORDER BY TeacherName DESC; 結果:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 4 | Ein | | 5 | Bill | | 6 | Bill | | 2 | Ben | +-----------+-------------+
ORDER BYを使用していない場合でも 各SELECT内の句 ステートメント、各SELECT ステートメントはかっこで囲み、ORDER BY 句(または任意のLIMIT 句)は最後のものの後にある必要があります。
(SELECT * FROM Teachers)
UNION
(SELECT * FROM Students)
ORDER BY TeacherName ASC; 結果:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 2 | Ben | | 5 | Bill | | 6 | Bill | | 3 | Cathy | | 4 | Cathy | | 4 | Ein | | 1 | Faye | | 2 | Jet | | 3 | Spike | | 1 | Warren | | 5 | Warren | +-----------+-------------+
かっこを省略すると、かっこを付けた場合と同じ結果が得られます。
SELECT * FROM Teachers
UNION
SELECT * FROM Students
ORDER BY TeacherName ASC; 結果:
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 2 | Ben | | 5 | Bill | | 6 | Bill | | 3 | Cathy | | 4 | Cathy | | 4 | Ein | | 1 | Faye | | 2 | Jet | | 3 | Spike | | 1 | Warren | | 5 | Warren | +-----------+-------------+
ソートする列がエイリアスを使用している場合、その列は(列名ではなく)そのエイリアスによって参照される必要があることに注意してください。
例:
(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY t ASC; 結果:
+--------+ | t | +--------+ | Ben | | Bill | | Cathy | | Ein | | Faye | | Jet | | Spike | | Warren | +--------+
エイリアスを使用しない場合は、次のようになります。
(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY TeacherName ASC; 結果:
ERROR 1054 (42S22): Unknown column 'TeacherName' in 'order clause'
各SELECTによって返される列の数 ステートメントは同じでなければなりません。したがって、次のことはできません。
SELECT TeacherName FROM Teachers
UNION
SELECT StudentId, StudentName FROM Students; 結果:
ERROR 1222 (21000): The used SELECT statements have a different number of columns
各SELECTの対応する位置にリストされている選択された列 ステートメントは同じデータ型である必要があります。ただし、そうでない場合は、UNIONの列のタイプと長さ 結果は、すべてのSELECTによって取得された値を考慮に入れます ステートメント。
TeacherNameを組み合わせようとするとどうなりますか StudentIdの列 列:
SELECT TeacherName FROM Teachers
UNION
SELECT StudentId FROM Students; 結果:
+-------------+ | TeacherName | +-------------+ | Warren | | Ben | | Cathy | | Bill | | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | +-------------+
他のいくつかのRDBMSはこの場合エラーを生成しますが、MySQLはエラーなしで出力を生成することができます。