To dość proste, kiedy to opanujesz:
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);
Ta linia zasadniczo porównuje S.S_Id ze wszystkimi e.S_Id wartości, które pochodzą z podzapytania.
Teraz zmień to na NOT EXISTS i umieść kontrolę równości S.S_Id = e.S_Id , wewnątrz podzapytania:
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);
Drobną możliwą zmianą jest uświadomienie sobie, że (SELECT e.S_Id ... tak naprawdę nie potrzebuje e.S_Id . Podzapytania z EXISTS i NOT EXISTS po prostu sprawdź, czy są zwracane wiersze, czy nie, a wartości kolumn nie mają znaczenia. Możesz umieścić SELECT * lub stała tam (SELECT 1 jest powszechne) lub SELECT NULL lub nawet SELECT 1/0 (Tak, to zadziała!):
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);
Inną ważną kwestią jest to, że podczas konwersji w ten sposób (pozornie równoważny) NOT EXISTS i NOT IN zapisy zapytania są naprawdę równoważne tylko wtedy, gdy oba S_Id kolumny nie mają wartości null. Jeśli e.S_Id kolumna jest dopuszczalna, NOT IN może spowodować, że całe zapytanie nie zwróci żadnych wierszy (ponieważ x NOT IN (a, b, c, ...) jest odpowiednikiem x<>a AND x<>b AND ... a warunek ten nie może być spełniony, gdy jeden z a,b,c... jest NULL .)
Z podobnych powodów uzyskasz różne wyniki, jeśli s.S_Id jest wartością null (w tym przypadku jest to mało prawdopodobne, ponieważ jest to prawdopodobnie klucz podstawowy, ale w innych przypadkach ma znaczenie).
Więc prawie zawsze lepiej jest użyć NOT EXISTS , ponieważ zachowuje się inaczej, nawet jeśli którakolwiek kolumna dopuszcza wartość null (S.S_Id = e.S_Id check usunie wiersze z wartością null wcześniej) i zwykle to zachowanie jest pożądane. W pytaniu jest wiele szczegółów: NIE W vs NIE ISTNIEJE
, w odpowiedzi @Martin Smith. Znajdziesz tam również sposoby na przekonwertowanie NOT IN na NOT EXISTS i zachowaj zerowe (nieprzyjemne) zachowanie.