サブクエリの操作

サブクエリは、別のクエリ内のクエリです。 FROM または WHERE 句のサブクエリは、含まれるクエリによって返されるデータを制限または比較/評価するために使用されるデータを提供するために使用されます。

このトピックの内容:

サブクエリのタイプ

相関サブクエリと非相関サブクエリ

サブクエリは、 相関 または 非相関 に分類できます。

  • 相関サブクエリは、サブクエリの外部からの1つ以上の列を参照します。(通常、列はサブクエリの WHERE 句内で参照されます。)相関サブクエリは、外部クエリ内のテーブルの各行でサブクエリが評価されたかのように、それが参照するテーブルのフィルターと考えることができます。

  • 非相関サブクエリには、そのような外部列参照はありません。これは独立したクエリであり、その結果は(行ごとではなく)外部のクエリに一度返されて使用されます。

例:

-- Uncorrelated subquery:
SELECT c1, c2
  FROM table1 WHERE c1 = (SELECT MAX(x) FROM table2);

-- Correlated subquery:
SELECT c1, c2
  FROM table1 WHERE c1 = (SELECT x FROM table2 WHERE y = table1.c2);

スカラーサブクエリと非スカラーサブクエリ

サブクエリは、 スカラー または 非スカラー に分類することもできます。

  • スカラーサブクエリは、単一の値(1行の1列)を返します。返される資格のある行がない場合、サブクエリは NULL を返します。

  • 非スカラーサブクエリは、0、1、または複数の行を返します。各行には1または複数の列が含まれる場合があります。各列で、返す値がない場合、サブクエリは NULL を返します。返される資格のある行がない場合、サブクエリは NULLs ではなく0行を返します。

Snowflakeでサポートされたタイプ

Snowflakeは現在、次のタイプのサブクエリをサポートしています。

  • 値式を使用できる任意の場所での無相関のスカラーサブクエリ。

  • WHERE 句の相関スカラーサブクエリ。

  • EXISTS、ANY / ALL、および IN サブクエリの WHERE 句。これらのサブクエリは、相関の場合と非相関の場合があります。

サブクエリ演算子

サブクエリ演算子 は、ネストされたクエリ式を操作します。これらは、次の値を計算するために使用できます。

  • SELECT リストで返された値。

  • GROUP BY 句でグループ化された値。

  • WHERE または HAVING 句の他の式と比較。

相関サブクエリと非相関サブクエリの違い

次のクエリは、 WHERE 句の非相関サブクエリを示しています。サブクエリはブラジルの1人当たり GDP を取得し、外部クエリは賃金がブラジルの1人当たり GDP 未満の(任意の国の)すべての仕事を選択します。サブクエリが返す値は外部クエリの列に依存しないため、サブクエリは無相関です。サブクエリは、外部クエリの実行中に一度だけ呼び出す必要があります。

SELECT p.name, p.annual_wage, p.country
  FROM pay AS p
  WHERE p.annual_wage < (SELECT per_capita_GDP
                           FROM international_GDP
                           WHERE name = 'Brazil');

次のクエリは、 WHERE 句の相関サブクエリを示しています。クエリは、その国の1人当たりの年収が GDP 未満の仕事をリストします。このサブクエリは、外部クエリの行ごとに1回呼び出され、行から値 p.country (国名)が渡されるため、相関しています。

SELECT p.name, p.annual_wage, p.country
  FROM pay AS p
  WHERE p.annual_wage < (SELECT MAX(per_capita_GDP)
                           FROM international_GDP i
                           WHERE p.country = i.name);

注釈

international_GDP テーブルには国ごとに1行しかないため、この場合、 MAX 集約関数は論理的に必要ありません。ただし、サーバーはそれを認識せず、サーバーはサブクエリが1行のみを返すことを要求するため、集約関数を使用して、サブクエリが実行されるたびにサブクエリが1行のみを返すことをサーバーに強制的に認識させます。

さらに、 MAX に加えて、 MIN または AVG も機能します。これらのいずれかを単一の値に適用すると、その値が変更されずに返されるためです。

スカラーサブクエリ

スカラーサブクエリは、最大で1行を返すサブクエリです。スカラーサブクエリは、 SELECT リスト、 GROUP BY 句、または WHERE または HAVING 句の関数への引数を含む、値式を表示できる任意の場所に表示できます。

使用上の注意

  • スカラーサブクエリでは、 SELECT リストに1つのアイテムのみを含めることができます。

  • スカラーサブクエリが複数の行を返す場合、ランタイムエラーが生成されます。

  • 現在、相関スカラーサブクエリは、1行を返すように静的に決定できる場合にのみサポートされます(例えば、 SELECT リストに GROUP BY のない集約関数が含まれる場合)。

  • 非相関スカラーサブクエリは、値式が許可される場所であればどこでもサポートされます。

  • FLATTEN 内に相関があるサブクエリは現在サポートされていません。

  • LIMIT / FETCH 句は、無相関スカラーサブクエリでのみ許可されます。

この例は、WHERE 句の基本的な非相関サブクエリを示しています。

SELECT employee_id
FROM employees
WHERE salary = (SELECT max(salary) FROM employees);

この例は、FROM 句の非相関サブクエリを示しています。この基本的なサブクエリは、 international_GDP テーブルの情報のサブセットを返します。全体的なクエリでは、仕事の年収がその国の per_capita_GDP と同じである「高賃金」国の仕事がリストされます。

SELECT p.name, p.annual_wage, p.country
  FROM pay AS p INNER JOIN (SELECT name, per_capita_GDP
                              FROM international_GDP
                              WHERE per_capita_GDP >= 10000.0) AS pcg
    ON pcg.per_capita_GDP = p.annual_wage AND p.country = pcg.name;

制限事項

サブクエリにはさまざまな SELECT ステートメントを含めることができますが、次の制限があります。

  • 一部の句は、ANY/ALL/NOT EXISTS サブクエリ内では許可されません。

  • LIMIT / FETCH 句を許可するサブクエリの唯一のタイプは、無相関スカラーサブクエリです。また、無相関スカラーサブクエリは1行のみを返すため、LIMIT 句にはサブクエリ内の実用価値がほとんどまたはまったくありません。