コツをつかめば、それはかなり簡単です:
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に関連する(不快な)動作を維持します。