サブクエリ¶
サブクエリは、別のクエリに組み込まれて、式またはビューの参照として機能するクエリです。
サブクエリは、クエリの SELECT
句、 FROM
句、または WHERE
句のいずれかに存在できます。
クエリの WHERE 句で使用するサブクエリ¶
クエリの WHERE 句のサブクエリの場合、「 SELECT ステートメントの構文 」 (<subselect condition>
の定義) では、サブクエリの出力を比較するために使用できる演算子の定義を取り上げています。
比較条件 ALL
、 ANY
、および IN
では、値をリストまたはサブクエリと比較します。比較条件の前には <
、 <=
、 =
、 <>
、 >=
、 >
を記述し、後ろにはサブクエリを記述する必要があります。
例 1
2,500 を超える収益を表示した flat_revenue
ビューにある taxid
の いずれか を、 incident
ビュー で taxid
とする行をすべて取得します。
以下の 2 つのクエリは互いに同等です。1 番目のクエリでは演算子 IN
を使用し、2 番目のクエリでは = ANY
の使用方法を示しています。
SELECT * FROM incident
WHERE taxid IN
(SELECT taxid
FROM flat_revenue
WHERE revenue > 2500)
SELECT * FROM incident
WHERE taxid = ANY
(SELECT taxid
FROM flat_revenue
WHERE revenue > 2500)
他のデータベース同様に、 ANY
は他の演算子と併用できます。たとえば、 taxid > ANY
..., taxid < ANY
..., のように使用できます。
例 2
internet_inc
から、 phone_inc
の行の ID と同じ ID の行を取得します。
SELECT *
FROM internet_inc AS a
WHERE EXISTS
(SELECT b.PINC_ID
FROM PHONE_INC AS b
WHERE a.iinc_id = b.pinc_id)
例 2 では、サブクエリの WHERE
句で、メインクエリ (internet_inc AS a
) の別名を使用しています。
WHERE
句にサブクエリを含むクエリは、実行時に準結合に変換されます。準結合とは、左辺のクエリの行のうち、右辺のクエリに一致する行をすべて返す関係演算です。通常の結合と同様に、クエリに応じた準結合法が Virtual DataPort サーバーによって選択されます。
サブクエリの準結合の実行で使用できる方法は、以下のとおりです。
マージ準結合: 結合属性によって並べ替え済みの行を処理します。可能な限り、Virtual DataPort ではこのアルゴリズムが選択されます。ほとんどの場合、この方法が最も効率的で、メモリ使用量が最少であるからです。
この方法は、結合の両辺が結合属性で並べ替え済みである場合にのみ選択できます。両辺のデータを JDBC データソースまたは ODBC データソースから取得する場合は、Virtual DataPort によって結合属性のフィールドで並べ替えられたデータが取得されます。そのために、データベースに送信されるクエリに ORDER BY 句が追加されます。
ハッシュ準結合: サブクエリが実行され、その結果がハッシュテーブルに格納されます。つづいて、Virtual DataPort サーバーによってメインクエリの結果の処理が始まり、ハッシュテーブルで一致が検索されます。マージ準結合の後では、この結合が最も効率的なアルゴリズムですが、必ず使用できるとは限りません。
ネスト化準結合 : メインクエリの結果にある行ごとにサブクエリが 1 回実行されます。
Virtual DataPort では、準結合の実行方法を選択する際に統計が使用されません。
通常の結合と同様に、クエリでは、サブクエリの準結合を実行するために Virtual DataPort サーバーで選択されたアルゴリズムを無視して、別のアルゴリズムを使用できます。そのためには、クエリプランの変更対象とするサブクエリの CONTEXT
句に SUBQUERYPLAN
修飾子を追加します。この修飾子の構文については「 CONTEXT 句の構文 」を参照してください。
SUBQUERYPLAN
修飾子は、メインクエリの CONTEXT
ではなく、変更するサブクエリの CONTEXT
で指定する必要があります。
以下に例を示します。
SELECT * FROM incidents
WHERE taxid IN
(SELECT taxid
FROM flat_revenue
WHERE revenue > 2500 CONTEXT (SUBQUERYPLAN = NESTED ORDERED))
この例の場合、Virtual DataPort サーバーでは、クエリの指定によってネスト化準結合のアルゴリズムが強制的に使用されます。
クエリの SELECT 句で使用するサブクエリ¶
SELECT
句のサブクエリは、関数内で使用される式の一部であっても、 SELECT
句の他の式と同様に機能します。メインクエリの各タプルの戻り値 (存在する場合) は、一意である必要があります。したがって、メインクエリの SELECT
句には 1 つの列のみ含めることができます。以下に例を示します。
SELECT i.incident_id
,(
SELECT sum(r.revenue)
FROM flat_revenue r
WHERE r.taxid = i.taxid
)
FROM incident i
SELECT
句にサブクエリを持つクエリは、実行時に左結合に変換されます。左側のクエリの行が右側のクエリで一致する行より多い場合、クエリは失敗します。
「 結合操作の最適化 」で説明しているように、クエリを実行する Virtual DataPort サーバーによって、結合ごとに結合方法が選択されます。サブクエリが相互に関連付けられている (上記の例のように、サブクエリに、サブクエリの外部のフィールドへの参照が含まれている) 場合、結合方法は常に ネスト になります。これにより、メインクエリから返される行ごとに、サブクエリが 1 回実行されます。