以下のSELECT文中のサブクエリーのpredicate_2内のエントリはいずれも、メイン クエリーのtable_list_1内のどの項も参照していないので、このサブクエリーは完全に独立した、相関ではない問合わせであるということです。独立したサブクエリーのことをローカル サブクエリーともいいます。
SELECT column_list_1 FROM table_list_1 WHERE predicate_1 (SELECT column_list_2 FROM table_list_2 WHERE predicate_2);
内問合わせと外問合わせの述部の関係を、相関関係と呼びます。上記の文中のサブクエリーは、外問合わせ中のテーブルを参照していないので非相関の問合わせと呼びます。このリクエストでは、サブクエリーがローカルなので、サブクエリーの反復回数は1回に限定されています。次に、その問合わせの結果は、外SELECT文によって作成された問合わせの結果と結合されます。
相関サブクエリーは、外問合わせの結果行ごとに1回ずつ括弧内のサブクエリーを実行します。サブクエリーが、サブクエリー自体の中で参照していない外問合わせ内のテーブルを参照している場合、そのサブクエリーは相関サブクエリーということになります。サブクエリーの結果が外問合わせとダイレクトに相関しているからです。相関サブクエリーを収容している外問合わせの各値ごとに、そのサブクエリーが1回ずつ実行されます。その場合、各実行ごとにそれぞれ固有の結果が生じるとは限りません。
以下の例は、相関サブクエリーの入ったSQLリクエストの動作を示したものです。
table_1に列col_1とcol_2があり、table_2に列col_3とcol_4があると仮定します。 つまり、この2つのテーブルには次の4つの行が存在します。
table_1 | table_2 | |||
---|---|---|---|---|
col_1 | col_2 | col_3 | col_4 | |
100 | 1 | 100 | 1 | |
50 | 1 | 50 | 1 | |
20 | 2 | 20 | 2 | |
40 | 2 | 40 | 2 |
以下のSELECT文は、WHERE句内の相関サブクエリーを使用して、table_1とtable_2を問合わせます。
SELECT * FROM table_1 WHERE col_1 IN (SELECT MAX(col_3) FROM table_2 WHERE table_1.col_2=table_2.col_4);
この文では、2つの応答行が返されます。table_1内の各行につき1回ずつ、サブクエリーが合計4回実行されるからです。
この結果に4つではなく2つの応答行しか入っていないのは、MAX(col_3)集約制約のためです(サブクエリーの2回の実行では、col_1が結果の中にない場合に応答行を1つ返します)。
- col_1=100, col_2=1
- col_1=40, col_2=2。
サブクエリーの4つの実行は、次のような応答行を返します。
col_3 | col_4 |
100 | 1 |
100 | 1 |
40 | 2 |
40 | 2 |
table_1の最初の行と4番目の行にのみ、この結果セットでcol_1の値が返されます。MAX集約関数を指定していなければ、table_1の4つの行がすべて返されていたはずです。