Sql-certificate-subqueries-to-solve-queries

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

クエリを解決するサブクエリ

サブクエリは、クエリ内のクエリとして最も適切に定義されます。 サブクエリを使用すると、クエリが実行時に実行されている間に実際に開発される基準のデータ行を選択するクエリを作成できます。 より正式には、別のSELECTステートメントのいずれかの句内でのSELECTステートメントの使用です。 実際、サブクエリを別のサブクエリ内に含めることができ、そのサブクエリは別のサブクエリ内にあります。 サブクエリは、INSERT、UPDATE、およびDELETEステートメント内にネストすることもできます。 サブクエリは括弧で囲む必要があります。

サブクエリは、単一の値を返す式であれば、どこでも使用できます。 つまり、単一の値を返すサブクエリも、FROM句のリストにオブジェクトとしてリストできます。 サブクエリがFROM句の一部として使用される場合、仮想テーブルまたはビューのように扱われるため、これはインラインビューと呼ばれます。 サブクエリは、メインクエリのFROM句、WHERE句、またはHAVING句のいずれかに配置できます。

Oracleでは、WHERE句で最大255のサブクエリレベルをネストできます。 FROM句で表現されたサブクエリのネストに制限はありません。実際には、3レベルまたは4レベルを超えてネストされたサブクエリに遭遇することはまれなので、255レベルの制限は実際にはまったく制限ではありません。

サブクエリのSELECTステートメントは、通常のクエリまたは外部クエリの開始に使用されるSELECTステートメントと非常によく似ています。サブクエリの完全な構文は次のとおりです。

( SELECT [DISTINCT] subquery_select_parameter
  FROM {table_name | view_name}
               {table_name | view_name} ...
  [WHERE search_conditions]
  [GROUP BY column_name [,column_name ] ...]
  [HAVING search_conditions] )

サブクエリの種類

  • 単一行サブクエリ:*単一行出力を返すサブクエリ。 WHERE条件で使用される場合、単一行比較演算子の使用をマークします。
  • 複数行のサブクエリ:*複数行の出力を返すサブクエリ。 IN、ANY、ALLなどの複数の行比較演算子を使用します。 複数の列を返すサブクエリもあります。
  • 相関サブクエリ:*相関サブクエリは、外部クエリによって提供されるデータに依存します。このタイプのサブクエリには、EXISTS演算子を使用して、指定された条件を満たすデータ行の存在をテストするサブクエリも含まれます。

単一行サブクエリ

単一行のサブクエリは、外部クエリの結果が単一の不明な値に基づいている場合に使用されます。 このクエリタイプは正式には「単一行」と呼ばれますが、名前はクエリが複数の列を返しますが、結果の1行のみを返すことを意味します。 ただし、単一行のサブクエリは、1つの列のみで構成される結果の1行のみを外部クエリに返すことができます。

以下のSELECTクエリでは、内部SQLは1行のみを返します。 会社の最低給与。 次に、この値を使用してすべての従業員の給与を比較し、給与が最低給与に等しい従業員のみを表示します。

SELECT first_name, salary, department_id
FROM employees
WHERE salary = (SELECT MIN (salary)
        FROM employees);

HAVING句は、クエリのグループ結果を何らかの条件に基づいて制限する必要がある場合に使用されます。 サブクエリの結果をグループ関数と比較する必要がある場合、外部クエリのHAVING句で内部クエリをネストする必要があります。

SELECT department_id, MIN (salary)
FROM employees
GROUP BY department_id
HAVING MIN (salary)  < (SELECT AVG (salary)
            FROM employees)

複数行サブクエリ

複数行のサブクエリは、結果の複数の行を親クエリに返すことができるネストされたクエリです。 複数行のサブクエリは、WHERE句およびHAVING句で最もよく使用されます。 複数の行を返すため、セット比較演算子(IN、ALL、ANY)で処理する必要があります。IN演算子は前の章で説明したのと同じ意味を持ちますが、ANY演算子は指定された値をサブクエリで返された各値と比較しますALLは、値をサブクエリによって返されるすべての値と比較します。

以下のクエリは、単一行のサブクエリが複数の行を返すときのエラーを示しています。

SELECT first_name, department_id
FROM employees
WHERE department_id = (SELECT department_id
            FROM employees
            WHERE LOCATION_ID = 100)
department_id = (select
               *
ERROR at line 4:
ORA-01427: single-row subquery returns more than one row

複数行演算子の使用

  • [> ALL]サブクエリによって返された最高値を超える
  • [<ALL]副照会によって返される最小値より小さい
  • [<ANY]サブクエリによって返される最大値未満
  • [> ANY]サブクエリによって返される最小値を超える *[= ANY]サブクエリによって返される値と等しい(INと同じ)

上記のSQLは、以下のようなIN演算子を使用して書き換えることができます。

SELECT first_name, department_id
FROM employees
WHERE department_id IN (SELECT department_id
                        FROM departments
                        WHERE LOCATION_ID = 100)

上記のクエリでは、INはサブクエリから返された部門IDと一致し、メインクエリの部門IDと比較して、条件を満たす従業員の名前を返します。

上記のクエリでは結合がより良いソリューションになりますが、説明のためにサブクエリが使用されています。

相関サブクエリ

外部クエリが内部クエリによって提供される値に依存する通常のサブクエリとは対照的に、相関サブクエリは、内部クエリが外部クエリによって提供される値に依存するサブクエリです。 これは、相関サブクエリでは、外部クエリによって選択される可能性のある行ごとに1回、内部クエリが繰り返し実行されることを意味します。

相関サブクエリは、複雑な管理の質問に答える結果テーブルを生成できます。

以下のSELECTクエリを検討してください。 以前に検討したサブクエリとは異なり、このSELECTステートメントのサブクエリは、メインクエリとは独立して解決できません。 外側のクエリは、e1というエイリアス名を持つ従業員テーブルから行が選択されることを指定していることに注意してください。 内部クエリは、エイリアスe2を持つ従業員テーブルの従業員部門番号列(DepartmentNumber)を、エイリアステーブル名e1の同じ列と比較します。

SELECT EMPLOYEE_ID, salary, department_id
FROM   employees E
WHERE salary > (SELECT AVG(salary)
                FROM   EMP T
                WHERE E.department_id = T.department_id)

複数列サブクエリ

複数列のサブクエリは、外部クエリに複数の列を返し、外部クエリのFROM、WHERE、またはHAVING句にリストできます。 たとえば、次のクエリは、現在の給与が1000〜2000の範囲にあり、部門10または20で働いている従業員の履歴詳細を示しています。

SELECT first_name, job_id, salary
FROM emp_history
WHERE (salary, department_id) in (SELECT salary, department_id
                  FROM employees
                  WHERE salary BETWEEN 1000 and 2000
                  AND department_id BETWEEN 10 and 20)
ORDER BY first_name;

複数列のサブクエリが外部クエリのFROM句で使用されると、外部クエリの他の句で参照できる一時テーブルが作成されます。 この一時テーブルは、より正式にはインラインビューと呼ばれます。 サブクエリの結果は、FROM句の他のテーブルと同様に扱われます。 一時テーブルにグループ化されたデータが含まれる場合、グループ化されたサブセットはテーブル内のデータの個別の行として扱われます。 以下のクエリのFROM句を検討してください。 サブクエリによって形成されるインラインビューは、メインクエリのデータソースです。

SELECT*
FROM (SELECT salary, department_id
    FROM employees
    WHERE salary BETWEEN 1000 and 2000);