Det är ganska enkelt när du får kläm på det:
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);
Den raden jämför i princip S.S_Id med alla e.S_Id värden som kommer från underfrågan.
Ändra nu det till NOT EXISTS och sätt en likhetskontroll S.S_Id = e.S_Id , inuti underfrågan:
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);
Mindre möjlig ändring är att inse att (SELECT e.S_Id ... behöver egentligen inte e.S_Id . Undersökningar med EXISTS och NOT EXISTS kolla bara om det finns rader som returneras eller inte och kolumnvärdena spelar ingen roll. Du kan sätta SELECT * eller en konstant där (SELECT 1 är vanligt) eller SELECT NULL eller till och med SELECT 1/0 (Ja, det kommer att fungera!):
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);
En annan viktig faktor är att när du gör omvandlingen på detta sätt, (till synes likvärdig) NOT EXISTS och NOT IN skrivningar av en fråga är egentligen likvärdiga endast om båda S_Id kolumner är inte nullbara. Om e.S_Id kolumnen är nullbar, NOT IN kan resultera i att hela frågan inte returnerar några rader alls (eftersom x NOT IN (a, b, c, ...) är ekvivalent med x<>a AND x<>b AND ... och det villkoret kan inte vara sant när någon av a,b,c... är NULL .)
Av liknande skäl kommer du att få andra resultat om s.S_Id är nullbar (det är inte särskilt troligt i det här fallet eftersom det förmodligen är den primära nyckeln men i andra fall spelar det roll.)
Så det är nästan alltid bättre att använda NOT EXISTS , eftersom den beter sig annorlunda även om endera kolumnen är nullbar (S.S_Id = e.S_Id check kommer att kassera rader med null tidigare) och vanligtvis är detta beteende det önskade. Det finns många detaljer i frågan: INTE IN vs INTE FINNS
, i svaret av @Martin Smith. Du hittar också sätt att konvertera NOT IN till NOT EXISTS och behålla det nollrelaterade (obehagliga) beteendet.