[データベース原則]リレーショナルデータベース標準言語SQLおよびリレーショナルデータベース管理システムSQLサーバー(5)

サブクエリ。

クエリブロックをWHERESELECT...FROM...WHERE...形式で含める場合、このクエリブロックはサブクエリまたはネストされたクエリと呼ばれ、それを含む外部クエリステートメントは親クエリと呼ばれます。ネストされたクエリは、一連の単純なクエリを複雑なクエリに構築し、クエリ機能を強化できます。サブクエリのネストレベルは最大255レベルに達する可能性があります。
ネストされたクエリは、実行中に内部から外部に処理されます。各サブクエリは、次のレベルの親クエリが処理される前に完了し、親クエリはサブクエリの結果を使用する必要があります。

通常のサブクエリ。

通常のサブクエリの実行順序は、最初にサブクエリを実行し、次にサブクエリの結果を親クエリのクエリ条件の値として使用します。通常のサブクエリは1回だけ実行され、親クエリに含まれるすべてのレコードがクエリ結果と比較されて、クエリ結果セットが決定されます。

  • [1つの値を返す通常のサブクエリ]サブクエリの戻り値が1つだけの場合、比較演算子を使用して親クエリとサブクエリを接続できます。

[例] Liu Wei先生と同じタイトルの先生の番号と名前を照会します。

SELECT TNo,TN
FROM T
WHERE Prof = (SELECT Prof FROM T WHERE TN='刘伟')

このクエリは、クエリを2つのクエリブロックに分割して実行することと同じです。最初に実行されるのはサブクエリです。

SELECT Prof 
FROM T 
WHERE TN = '刘伟'

サブクエリは値、つまりLiu Wei先生のタイトル-"Lecturer"を返し、これを親クエリの条件として使用してから、親クエリを実行して教師の番号と教師の名前を見つけます。

  • [値のセットを返す通常のサブクエリ]サブクエリの戻り値が複数であるがセットである場合、クエリ演算子の条件を表すために比較演算子を直接使用することはできませんが、キーワードANYを使用する必要がありますALL

[例]コースC5を担当する先生の名前を問い合わせる。

SELECT TN 
FROM T
WHERE TNo = ANY (SELECT TNo FROM TC WHERE CNo='C5')

最初にサブクエリを実行して、コースC5を教える教師の教師IDのセットを見つけ、次に親クエリを実行します。TNoがサブクエリの結果セットの値と等しい限り、教師がコースを教えていることを意味し、対応するTNが配置されます最終的なクエリ結果を入力します。もちろん、このクエリは以下を接続することでも実現できます。

SELECT TN
FROM T,TC
WHERE T.TNo=TC.TNo AND CNo='C5'

[例]コンピュータ部門の教師より給与が高い他の部門の教師の名前と給与を照会します。

SELECT TN,Sal
FROM T
WHERE Sal > ANY(
				   SELECT Sal FROM T WHERE Dept='计算机'
				 ) 
	  AND Dept!='计算机'

論理的な観点から見ると、コンピュータ部門の教師の給与よりも高く、コンピュータ部門の教師の最低給与よりも高い必要があるだけなので、次のコードを使用できます。

SELECT TN,Sal
FROM T
WHERE SaL > (SELECT MIN(Sal) FROM T WHERE Dept='计算机')
	  AND Dept!='计算机'

最初にサブクエリとMIN()関数を使用して、コンピュータ部門の最低給与xを見つけ、次に親クエリを実行して、コンピュータ部門にいない教師の中から、給与がxより高い教師の名前と給与を見つけます。

[例]コースC5を担当する教師の名前を問い合わせ、キーワードを使用するIN

SELECT TN
FROM T
WHERE TNo IN(SELECT TNo FROM TC WHERE CNo='C5')

[例]コンピュータ部門のすべての教師より給与が高い他の部門の教師の名前と給与を照会します。

SELECT TN,Sal
FROM T
WHERE Sal >ALL(SELECT SAL FROM T WHERE Dept = '计算机')
	  AND Dept!='计算机'

上記のライブラリ関数MIN()使用例のように、ライブラリ関数MAX()使用して、すべてのコンピューター教師よりも高い給与を達成することもできます

SELECT TN,Sal
FROM T
WHERE Sal >(SELECT MAX(Sal) FROM T WHERE Dept='计算机')
	  AND Dept!='计算机'

関連するサブクエリ。

以前のすべてのサブクエリは通常のサブクエリであり、親クエリがサブクエリの結果をクエリ条件として使用することを除いて、これらのサブクエリと親クエリの間に相互作用はありません。ただし、サブクエリのクエリ条件で親クエリテーブルの属性値を参照する必要がある場合があります。このタイプのクエリを相関サブクエリと呼びます。
通常のサブクエリと比較して、相関サブクエリの実行順序ははるかに複雑です。まず、親クエリテーブルのレコードの最初の行を選択します。内部サブクエリはこの行の関連する属性値を使用してクエリを実行し、次に親クエリは、サブクエリによって返された結果に基づいて、この行がクエリ条件を満たすかどうかを判断します。条件が満たされた場合、この行を親クエリのクエリ結果セットに入れます。親クエリテーブルのデータの各行が処理されるまで、このプロセスを繰り返します。これから、関連するサブクエリの実行数が親クエリテーブルの行数によって決まることもわかります。

【例】コースC5を教えていない先生の名前を問い合わせる。

SELECT DISTINCT TN
FROM T
WHERE 'C5'!=ALL(SELECT CNo FROM TC WHERE TNo=T.TNo)

!=ALLの意味は、サブクエリの結果のどの値とも等しくNOT INなく、代わりに使用することもできます。27ページの関係テーブルに基づいて、この相関サブクエリのプロセスを説明します。最初に、レコード[T1、Li Li、男性、47、教授、1500、3000、コンピューター]である親関係テーブルTの行を選択してから、サブクエリを入力します。見つかったCNoセットは{C1、C4}、 C5は含まれていないため、レコードはクエリ条件を満たすため、TN列に射影します。つまり、レコード[Li Li]が最終結果セットに入ります。その後のプロセスは同じです。キーワードを
使用EXISTSして、関連するサブクエリ(EXISTS存在を示す量指定子)を実行することもできます。このキーワードを使用したサブクエリは結果を返さず、ブール値のTrueまたはFalseを返します。

【例】コースC5を担当する先生の名前を問い合せ、EXISTSキーワードを使用する。

SELECT TN
FROM T
WHERE EXISTS(SELECT * FROM TC WHERE TNo=T.TNo AND CNo='C5')

サブクエリのTCテーブルの行が条件を満たすと、親クエリはTテーブルのタプルをTN列に射影し、それを結果セットに入れます。

【例】コースC5を教えていない先生の名前を問い合せ、EXISTSキーワードを使用する。

SELECT TN
FROM T
WHERE (NOT EXISTS(SELECT * FROM TC WHERE TNo=T.TNo AND CNo='C5'))

[例]すべてのコースを受講した学生の名前を照会します。

SELECT SN
FROM S
WHERE NOT EXISTS
(
	SELECT *
	FROM C
	WHERE NOT EXISTS
	(
		SELECT *
		FROM SC
		WHERE SNo=S.SNo AND CNo=C.CNo
	)
)	 

すべてのコースを受講した学生は、次のように理解することもできます。この学生xには、そのようなコースyはなく、コース選択テーブルSCに<x、y>の組み合わせの記録はありません。
27ページの関係テーブルにデータが追加され、実際にすべてのコースを受講した学生がいます。表を以下に示します。学生S1は7つのコースをすべて受講しました。
ここに画像の説明を挿入
実行結果は次のとおりです。
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_44246009/article/details/108049756