Het is vrij eenvoudig, als je het onder de knie hebt:
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);
Die regel vergelijkt in feite S.S_Id
met alle e.S_Id
waarden die uit de subquery komen.
Verander dat nu in NOT EXISTS
en plaats een gelijkheidscontrole S.S_Id = e.S_Id
, in de subquery:
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);
Een kleine mogelijke verandering is om te beseffen dat (SELECT e.S_Id ...
heeft de e.S_Id
niet echt nodig . Subquery's met EXISTS
en NOT EXISTS
controleer gewoon of er rijen zijn geretourneerd of niet en de kolomwaarden doen er niet toe. U kunt SELECT *
of een constante daar (SELECT 1
is gebruikelijk) of SELECT NULL
of zelfs SELECT 1/0
(Ja, dat zal werken!):
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);
Een andere belangrijke overweging is dat wanneer u de conversie op deze manier uitvoert, de (schijnbaar equivalente) NOT EXISTS
en NOT IN
geschriften van een query zijn alleen echt equivalent als beide S_Id
kolommen zijn niet nullable. Als de e.S_Id
kolom is nullable, de NOT IN
kan ertoe leiden dat de hele zoekopdracht helemaal geen rijen retourneert (omdat x NOT IN (a, b, c, ...)
is gelijk aan x<>a AND x<>b AND ...
en die voorwaarde kan niet waar zijn als een van de a,b,c...
is NULL
.)
Om vergelijkbare redenen krijgt u andere resultaten als de s.S_Id
is nullable (dat is in dit geval niet erg waarschijnlijk omdat het waarschijnlijk de primaire sleutel is, maar in andere gevallen is het van belang.)
Het is dus bijna altijd beter om NOT EXISTS
. te gebruiken , omdat het zich anders gedraagt, zelfs als een van beide kolommen nullable is (de S.S_Id = e.S_Id
check verwijdert eerder rijen met null) en meestal is dit het gewenste gedrag. De vraag bevat veel details: NIET IN vs NIET BESTAAT
, in het antwoord van @Martin Smith. Je zult ook manieren vinden om de NOT IN
. te converteren naar NOT EXISTS
en behoud het null-gerelateerde (onaangename) gedrag.