EXISTS and NOT EXISTS are boolean operators that check whether a subquery returns rows. They are fast, NULL-safe, and perfect for presence checks or anti-joins compared with IN/NOT IN.
| Operator | Meaning |
|---|---|
| EXISTS | Returns TRUE once the subquery finds a match. |
| NOT EXISTS | Returns TRUE if the subquery returns no rows. |
| Customers | Orders |
|---|---|
| 1 β Suresh | 101 β Cust 1 β 500 |
| 2 β Priya | 102 β Cust 1 β 200 |
| 3 β John | 103 β Cust 2 β 700 |
SELECT c.CustName
FROM Customers c
WHERE EXISTS (
SELECT 1
FROM Orders o
WHERE o.CustID = c.CustID
);
SELECT c.CustName
FROM Customers c
WHERE NOT EXISTS (
SELECT 1
FROM Orders o
WHERE o.CustID = c.CustID
);
LEFT JOIN with WHERE o.CustID IS NULL, but often faster.-- Using IN
SELECT CustName
FROM Customers
WHERE CustID IN (SELECT CustID FROM Orders);
-- Using EXISTS
SELECT CustName
FROM Customers c
WHERE EXISTS (
SELECT 1 FROM Orders o
WHERE o.CustID = c.CustID
);
EXISTS stops after the first match, handles NULL values, and is preferred for large correlated datasets.
SELECT c.CustName
FROM Customers c
WHERE NOT EXISTS (
SELECT 1
FROM Orders o
WHERE o.CustID = c.CustID
);
SELECT c.CustName
FROM Customers c
WHERE EXISTS (
SELECT 1
FROM Orders o
WHERE o.CustID = c.CustID
AND o.Amount > 500
);
| Feature | EXISTS | IN |
|---|---|---|
| Execution | Stops after first match | Evaluates full list |
| NULL handling | Safe | Can return no rows if list has NULL |
| Performance | Better for large datasets | Slower on big correlated subqueries |
| Readability | Great for presence checks | Simple for static lists |
SELECT c.CustName
FROM Customers c
WHERE EXISTS (
SELECT 1
FROM Orders o
WHERE o.CustID = c.CustID
AND EXISTS (
SELECT 1
FROM Products p
WHERE p.ProductID = o.ProductID
AND p.InStock = 1
)
);
Identify customers with or without active purchases.
Detect orphaned rows without related records.
Verify API responses based on underlying database relationships.
Check accounts without transactions or with flagged activity.
SELECT 1 inside EXISTS for minimal overhead.NOT EXISTS over NOT IN when NULLs are possible.CustID, ProductID) to accelerate lookups.IN for static lists of literal values.IN/NOT IN.β