>>-+-subselect---------+----------------------------------------> +-(fullselect)------+ '-| values-clause |-' .---------------------------------------------------. V | >--------+---------------------------------------------+--+---->< '--+- UNION------+---+-subselect---------+--' +- UNION ALL--+ +-(fullselect)------+ +-EXCEPT--------+ '-| values-clause |-' +-EXCEPT ALL----+ +-INTERSECT-----+ '-INTERSECT ALL-' values-clause .-,------------------. V | |---VALUES-------| Values-row |---+----------------------------| Values-row |---+--+-expression-+---------------+---------------------------| | '-NULL-------' | | .-,-----------------. | | V | | '-(------+-expression-+--+---)--' '-NULL-------'
全選択 (fullselect) は、選択ステートメント、 INSERT ステートメント、および CREATE VIEW ステートメントの構成要素の 1 つです。 また、これはステートメントの構成要素である特定の述部の構成要素ともなります。 述部の構成要素である全選択 は、 副照会 (subquery) と呼ばれます。 括弧で囲んだ全選択 (fullselect) は、 副照会と呼ばれることがあります。
セット演算子である UNION、EXCEPT、および INTERSECT は、 関係演算子の合併、差、積に対応しています。
全選択 は結果表を指定します。 集合演算子を使用しない全選択 の結果は、 指定した副選択または VALUES 文節の結果になります。
NULL は、複数の Values-row でのみ使用することができ、 同一列の少なくとも 1 行は NULL 以外でなければなりません (SQLSTATE 42826)。
Values-row は以下によって指定されます。
複数行からなる Values-clause には、 各 Values-row に同数の式が必要です (SQLSTATE 42826)。
次に、Values-clause の例とその意味を示します。
VALUES (1),(2),(3) - 3 rows of 1 column VALUES 1, 2, 3 - 3 rows of 1 column VALUES (1, 2, 3) - 1 row of 3 columns VALUES (1,21),(2,22),(3,23) - 3 rows of 2 columns
Values-clause は、 n 個の Values-row RE1 〜 REn (n は 2 以上) で構成され、 以下と同等です。
RE1 UNION ALL RE2 ... UNION ALL REn
これは、各 Values-row に対応する式は比較可能でなければならず (SQLSTATE 42825)、 結果のデータ・タイプは 結果のデータ・タイプに関する規則 に基づくことを意味しています。
結果表 R1 の中の列の数と R2 の中の列の数は、 同じでなければなりません (SQLSTATE 42826)。 ALL キーワードを指定しない場合、R1 および R2 には、 255 バイトよりも大きいと宣言されたストリング列を含めてはなりません。 また、データ・タイプが LONG VARCHAR、LONG VARGRAPHIC、 BLOB、CLOB、DBCLOB、DATALINK であるストリング列や、 それらのタイプのいずれかを基にした特殊タイプ、 または構造タイプであるストリング列を含めることもできません (SQLSTATE 42907)。
結果の列の名前は、次のようになります。
生成された名前を調べるには、SQL ステートメントの DESCRIBE を実行して、 SQLNAME フィールドを参照します。
2 つの行が互いに重複していると言えるのは、 最初の行の各値が 2 番目の行の対応する値に等しい場合です。 (重複を判別する場合、2 つのヌル値は等しいものとみなされます)。
複数の演算を 1 つの式の中に結合した場合は、括弧内の演算が先に実行されます。 括弧がない場合、演算は左から右に実行されますが、例外として、 すべての INTERSECT 演算は UNION または EXCEPT の演算の前に実行されます。
次の例では、表 R1 と R2 の値を左端に示しています。
他にリストされている見出しは、R1 と R2 の種々のセット演算の結果の値を示しています。
R1 | R2 | UNION ALL | UNION | EXCEPT ALL | EXCEPT | INTER- SECT ALL | INTER- SECT |
---|---|---|---|---|---|---|---|
1 | 1 | 1 | 1 | 1 | 2 | 1 | 1 |
1 | 1 | 1 | 2 | 2 | 5 | 1 | 3 |
1 | 3 | 1 | 3 | 2 |
| 3 | 4 |
2 | 3 | 1 | 4 | 2 |
| 4 |
|
2 | 3 | 1 | 5 | 4 |
|
|
|
2 | 3 | 2 |
| 5 |
|
|
|
3 | 4 | 2 |
|
|
|
|
|
4 |
| 2 |
|
|
|
|
|
4 |
| 3 |
|
|
|
|
|
5 |
| 3 |
|
|
|
|
|
|
| 3 |
|
|
|
|
|
|
| 3 |
|
|
|
|
|
|
| 3 |
|
|
|
|
|
|
| 4 |
|
|
|
|
|
|
| 4 |
|
|
|
|
|
|
| 4 |
|
|
|
|
|
|
| 5 |
|
|
|
|
|
結果列のデータ・タイプの判別の規則については、 結果のデータ・タイプに関する規則 を参照してください。
ストリング列の変換の処理方法の規則については、 ストリング変換に関する規則 を参照してください。
例 1: EMPLOYEE 表からすべての列と行を選択します。
SELECT * FROM EMPLOYEE
例 2: EMPLOYEE 表の従業員で、 その部門番号 (WORKDEPT) が 'E' で始まる部門に属しているか、 またはプロジェクト番号 (PROJNO) が 'MA2100'、'MA2110'、 または 'MA2112' である EMP_ACT 表のプロジェクトに割り当てられている従業員すべての従業員番号 (EMPNO) をリストします。
SELECT EMPNO FROM EMPLOYEE WHERE WORKDEPT LIKE 'E%' UNION SELECT EMPNO FROM EMP_ACT WHERE PROJNO IN('MA2100', 'MA2110', 'MA2112')
例 3: 例 2 と同じ照会を行い、さらに EMPLOYEE 表の行には 'emp'、 EMP_ACT 表の行には 'emp_act' という "タグ" を付けます。 例 2 の結果とは異なり、この照会では、同じ EMPNO が複数回戻され、 付加される "タグ" によりどの表からとられたかが示されます。
SELECT EMPNO, 'emp' FROM EMPLOYEE WHERE WORKDEPT LIKE 'E%' UNION SELECT EMPNO, 'emp_act' FROM EMP_ACT WHERE PROJNO IN('MA2100', 'MA2110', 'MA2112')
例 4: 例 2 と同じの照会を行いますが、重複行が除去されないように UNION ALL を使用します。
SELECT EMPNO FROM EMPLOYEE WHEREWORKDEPTLIKE 'E%' UNION ALL SELECT EMPNO FROM EMP_ACT WHERE PROJNO IN('MA2100', 'MA2110', 'MA2112')
例 5: 例 3 と同じ照会を行いますが、現在どの表にもない 2 人の従業員を追加して、 それらの行に "new" というタグを付けます。
SELECT EMPNO, 'emp' FROM EMPLOYEE WHEREWORKDEPTLIKE 'E%' UNION SELECT EMPNO, 'emp_act' FROM EMP_ACT WHERE PROJNO IN('MA2100', 'MA2110', 'MA2112') UNION VALUES ('NEWAAA', 'new'), ('NEWBBB', 'new')
例 6: この EXCEPT の例は、T1 に存在し、T2 に存在しない行をすべて生成します。
(SELECT * FROM T1) EXCEPT ALL (SELECT * FROM T2)
NULL 値が含まれていない場合、この例は次の例と同じ結果を戻します。
SELECT ALL * FROM T1 WHERE NOT EXISTS (SELECT * FROM T2 WHERE T1.C1 = T2.C1 AND T1.C2 = T2.C2 AND...)
例 7: この INTERSECT の例は、表 T1 と T2 の両方にあるすべての行を生成し、 重複した行を除去します。
(SELECT * FROM T1) INTERSECT (SELECT * FROM T2)
NULL 値が含まれていない場合、この例は次の例と同じ結果を戻します。
SELECT DISTINCT * FROM T1 WHERE EXISTS (SELECT * FROM T2 WHERE T1.C1 = T2.C1 AND T1.C2 = T2.C2 AND...)
ここで、C1、C2、などは T1 と T2 の列を表します。