コツをつかめば、それはかなり簡単です:
SELECT s.S_Fname, s.S_Lname
FROM STUDENT s
WHERE s.S_Sex = 'F'
AND S.S_Id NOT IN(SELECT e.S_Id -- take this line
FROM ENROLLMENT e
WHERE e.Mark < 70);
その行は基本的にS.S_Idを比較します すべてのe.S_Id サブクエリからの値。
次に、これをNOT EXISTSに変更します。 等価性チェックを行いますS.S_Id = e.S_Id 、サブクエリ内:
SELECT s.S_Fname, s.S_Lname
FROM STUDENT s
WHERE s.S_Sex = 'F'
AND NOT EXISTS (SELECT e.S_Id
FROM ENROLLMENT e
WHERE (e.Mark < 70) -- if this is complex, you'll need parentheses
AND S.S_Id = e.S_Id);
マイナーな変更は、(SELECT e.S_Id ... e.S_Idは実際には必要ありません 。 EXISTSを使用したサブクエリ およびNOT EXISTS 行が返されるかどうかを確認するだけで、列の値は重要ではありません。 SELECT *を置くことができます またはそこに定数(SELECT 1 一般的です)またはSELECT NULL またはSELECT 1/0 (はい、それでうまくいきます!):
SELECT s.S_Fname, s.S_Lname
FROM STUDENT s
WHERE s.S_Sex = 'F'
AND NOT EXISTS (SELECT 1
FROM ENROLLMENT e
WHERE e.Mark < 70
AND S.S_Id = e.S_Id);
もう1つの重要な考慮事項は、この方法で変換を行う場合、(一見同等の)NOT EXISTSであるということです。 およびNOT IN クエリの記述は、両方のS_Idの場合にのみ、実際には同等です。 列はNULL可能ではありません。 e.S_Idの場合 列はNULL可能であり、NOT IN クエリ全体で行がまったく返されない場合があります(x NOT IN (a, b, c, ...) x<>a AND x<>b AND ...と同等です a,b,c...のいずれかである場合、その条件は真にはなりません。 NULLです 。)
同様の理由で、s.S_Idの場合、結果は異なります。 null許容型です(おそらく主キーであるため、この場合はあまりありそうにありませんが、それ以外の場合は重要です)。
したがって、ほとんどの場合、NOT EXISTSを使用することをお勧めします。 、どちらかの列がnull許容であっても動作が異なるため(S.S_Id = e.S_Id チェックは以前にnullの行を破棄します)、通常、この動作が必要です。質問には多くの詳細があります: NOT IN vs NOT EXISTS
、@MartinSmithによる回答。 NOT INを変換する方法もあります NOT EXISTS nullに関連する(不快な)動作を維持します。