Sql-certificate-using-the-set-operators

提供:Dev Guides
移動先:案内検索

集合演算子の使用

セット演算子は、2つ(またはそれ以上)のSELECTステートメントの結果を結合するために使用されます。Oracle11gで使用可能なSET演算子は、UNION、UNION ALL、INTERSECT、およびMINUSです。

UNION集合演算子は、2つのSELECTステートメントの結合結果を返します。本質的に、結果から重複を削除します。 重複した結果ごとに1行のみがリストされます。この動作に対抗するには、最終結果で重複を保持するUNION ALLセット演算子を使用します。INTERSECTは、両方のSELECTクエリに共通するレコードのみをリストします。 MINUS集合演算子は、最初のクエリの結果にも2番目のクエリの結果が見つかった場合、その結果を削除します。 INTERSECTおよびMINUS集合演算は、重複しない結果を生成します。

すべてのSET演算子は、それらの間で同程度の優先順位を共有します。その代わりに、Oracleは、クエリの実行中に、左から右または上から下へ評価を開始します。ぶら下がり演算子。

覚えておくべきポイント-

  • 関係するすべてのSELECTステートメントで同じ数の列を選択する必要があります。表示で使用される列名は、最初のクエリから取得されます。
  • 列リストのデータ型は、oracleによって互換性/暗黙的に変換可能である必要があります。 コンポーネントクエリの対応する列が異なるデータ型グループに属している場合、Oracleは暗黙的な型変換を実行しません。たとえば、最初のコンポーネントクエリの列がデータ型であり、2番目のコンポーネントクエリの対応する列がデータである場合タイプCHAR、Oracleは暗黙的な変換を実行しませんが、ORA-01790エラーを発生させます。
  • 結果セットをソートするには、位置の順序付けを使用する必要があります。 Set演算子では、個々の結果セットの順序付けは許可されていません。 ORDER BYは、クエリの最後に1回出現できます。 例えば、
  • UNIONおよびINTERSECT演算子は可換です。 クエリの順序は重要ではありません。最終結果は変わりません。
  • パフォーマンスの面では、UNION ALLは、重複のフィルタリングと結果セットのソートでリソースが無駄にならないため、UNIONと比較してパフォーマンスが向上しています。
  • 集合演算子はサブクエリの一部になることができます。
  • 集合演算子は、TABLEコレクション式を含むSELECTステートメントでは使用できません。 *LONG、BLOB、CLOB、BFILE、VARRAY、またはネストした表は、集合演算子では使用できません。集合演算子では、更新句は使用できません。

連合

UNION演算子を使用して複数のSELECTクエリを結合する場合、Oracleは、すべての重複したSELECTクエリの結合結果を、NULL値を無視せずにすべての重複を削除し、並べ替えられた順序(デフォルトで昇順)で表示します。

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とUNION ALLは、機能がわずかに異なりますが類似しています。 ただし、UNION ALLは、重複を削除してデータを並べ替えることなく結果セットを提供します。 たとえば、上記のクエリでは、効果を確認するためにUNIONがUNION ALLに置き換えられます。

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

交絡

INTERSECT演算子を使用して、Oracleは両方の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ステートメントの選択された列のカウントとデータ型が異なる場合があります。 したがって、列リストを明示的に一致させるために、各SELECTステートメントで選択された列の数とデータ型が一致するように、欠落した位置にNULL列が挿入されます。 数値列の場合、クエリで選択された列のタイプに合わせてゼロを置き換えることもできます。

次のクエリでは、従業員名(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操作でのORDER BY句の使用

ORDER BY句は、複合SELECTステートメントを含むクエリの最後に1回だけ表示できます。個々のSELECTステートメントにORDER BY句を含めることはできません。 さらに、最初のSELECTクエリにのみ表示される列に基づいて並べ替えを行うことができます。 このため、列の位置を使用して複合クエリをソートすることをお勧めします。

以下の複合クエリは、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;