集合演算子の使用
集合演算子は、2つ(またはそれ以上)のSELECTステートメントの結果を結合するために使用されます。Oracle11gで使用可能なSET演算子は、UNION、UNION ALL、INTERSECT、およびMINUSです。
UNION集合演算子は、2つのSELECTステートメントの結合された結果を返します。基本的に、結果から重複を削除します。つまり、複製された結果ごとに1つの行のみがリストされます。この動作に対抗するには、で重複を保持するUNIONALL集合演算子を使用します。最終結果。INTERSECTは、両方のSELECTクエリに共通のレコードのみをリストします。MINUS set演算子は、2番目のクエリの結果が最初のクエリの結果にも含まれている場合、それらを出力から削除します。INTERSECTおよびMINUSセット操作は、重複しない結果を生成します。
すべてのSET演算子は、それらの間で同じ程度の優先順位を共有します。代わりに、クエリの実行中に、Oracleは左から右または上から下に評価を開始します。明示的に括弧が使用されている場合、括弧が優先されるため、順序が異なる場合があります。ぶら下がり演算子。
覚えておくべきポイント-
参加しているすべてのSELECTステートメントで同じ数の列を選択する必要があります。表示で使用される列名は、最初のクエリから取得されます。
列リストのデータ型は、Oracleによって互換性がある/暗黙的に変換可能である必要があります。コンポーネントクエリの対応する列が異なるデータ型グループに属している場合、Oracleは暗黙的な型変換を実行しません。たとえば、最初のコンポーネントクエリの列がデータ型DATEで、2番目のコンポーネントクエリの対応する列がデータの場合タイプCHAR、Oracleは暗黙的な変換を実行しませんが、ORA-01790エラーを発生させます。
結果セットをソートするには、位置順を使用する必要があります。集合演算子では、個々の結果セットの順序付けは許可されていません。ORDER BYは、クエリの最後に1回表示できます。例えば、
UNION演算子とINTERSECT演算子は可換です。つまり、クエリの順序は重要ではありません。最終結果は変わりません。
パフォーマンスに関しては、UNION ALLは、重複のフィルタリングと結果セットの並べ替えにリソースが浪費されないため、UNIONと比較して優れたパフォーマンスを示します。
集合演算子は、サブクエリの一部にすることができます。
集合演算子は、TABLEコレクション式を含むSELECTステートメントでは使用できません。
LONG、BLOB、CLOB、BFILE、VARRAY、またはネストされたテーブルは、集合演算子での使用は許可されていません。更新句は、集合演算子では許可されていません。
連合
UNION演算子を使用して複数のSELECTクエリを結合すると、Oracleは、NULL値を無視せずに、すべての重複を削除した後、ソートされた順序(デフォルトでは昇順)で、すべての複合SELECTクエリからの結合結果を表示します。
UNION演算子を使用して結合された以下の5つのクエリについて考えてみます。最終的に結合された結果セットには、すべてのSQLからの値が含まれます。データの重複の削除と並べ替えに注意してください。
SELECT 1 NUM FROM DUAL
UNION
SELECT 5 FROM DUAL
UNION
SELECT 3 FROM DUAL
UNION
SELECT 6 FROM DUAL
UNION
SELECT 3 FROM DUAL;
NUM
-------
1
3
5
6
なお、SELECTクエリで選択される列は、互換性のあるデータ型である必要があります。ルールに違反すると、Oracleはエラーメッセージをスローします。
SELECT TO_DATE('12-OCT-03') FROM DUAL
UNION
SELECT '13-OCT-03' FROM DUAL;
SELECT TO_DATE('12-OCT-03') FROM DUAL
*
ERROR at line 1:
ORA-01790: expression must have same datatype as corresponding expression
UNION ALL
UNIONとUNIONALLは機能が似ていますが、わずかな違いがあります。ただし、UNION ALLは、重複を削除したりデータを並べ替えたりせずに結果セットを提供します。たとえば、上記のクエリでは、効果を確認するためにUNIONをUNIONALLに置き換えています。
UNIONセクションで示されているクエリについて考えてみます。並べ替えと重複排除なしで生成される出力の違いに注意してください。
SELECT 1 NUM FROM DUAL
UNION ALL
SELECT 5 FROM DUAL
UNION ALL
SELECT 3 FROM DUAL
UNION ALL
SELECT 6 FROM DUAL
UNION ALL
SELECT 3 FROM DUAL;
NUM
-------
1
5
3
6
3
交差する
Oracleは、INTERSECT演算子を使用して、両方のSELECTステートメントの共通行を表示します。重複はなく、データはソートされた順序(デフォルトでは昇順)に配置されます。
たとえば、以下のSELECTクエリは、部門10と20で共通の給与を取得します。ISOSQL標準に従って、INTERSECTは集合演算子の評価よりも優先されますが、これはまだOracleに組み込まれていません。
SELECT SALARY
FROM employees
WHERE DEPARTMENT_ID = 10
INTRESECT
SELECT SALARY
FROM employees
WHERE DEPARTMENT_ID = 20
SALARY
---------
1500
1200
2000
マイナス
マイナス演算子は、最初のクエリには存在するが2番目のクエリには存在しない行を表示します。デフォルトでは、重複やデータは昇順で並べられていません。
SELECT JOB_ID
FROM employees
WHERE DEPARTMENT_ID = 10
MINUS
SELECT JOB_ID
FROM employees
WHERE DEPARTMENT_ID = 20;
JOB_ID
-------------
HR
FIN
ADMIN
SELECTステートメントの一致
複合SELECTステートメントで、選択した列のカウントとデータ型が異なる場合があります。したがって、列リストを明示的に一致させるために、行方不明の位置にNULL列が挿入され、各SELECTステートメントで選択された列の数とデータ型が一致します。数値列の場合、クエリで選択された列のタイプに一致するようにゼロに置き換えることもできます。
以下のクエリでは、従業員名(varchar2)と場所ID(番号)のデータ型が一致していません。したがって、以下のクエリを実行すると、互換性の問題によりエラーが発生します。
SELECT DEPARTMENT_ID "Dept", first_name "Employee"
FROM employees
UNION
SELECT DEPARTMENT_ID, LOCATION_ID
FROM departments;
ERROR at line 1:
ORA-01790: expression must have same datatype as corresponding expression
明示的に、場所IDと従業員名をNULLに置き換えることで、列を照合できます。
SELECT DEPARTMENT_ID "Dept", first_name "Employee", NULL "Location"
FROM employees
UNION
SELECT DEPARTMENT_ID, NULL "Employee", LOCATION_ID
FROM departments;
SET操作でのORDERBY句の使用
ORDER BY句は、複合SELECTステートメントを含むクエリの最後に1回だけ表示できます。これは、個々のSELECTステートメントにORDERBY句を含めることができないことを意味します。さらに、並べ替えは、最初のSELECTクエリにのみ表示される列に基づいて行うことができます。このため、列の位置を使用して複合クエリを並べ替えることをお勧めします。
以下のcompundクエリは、2つの部門からの結果を統合し、SALARY列で並べ替えます。
SELECT employee_id, first_name, salary
FROM employees
WHERE department_id=10
UNION
SELECT employee_id, first_name, salary
FROM employees
WHERE department_id=20
ORDER BY 3;