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はエラーなしで出力を生成することができます。