SQL EXISTS and NOT EXISTS
EXISTS answers a yes/no question for each outer row: does a matching row exist in another query?
EXISTS keeps a row when the subquery finds at least one match.
NOT EXISTS keeps a row when the subquery finds no matches. The
selected value inside the subquery doesn't matter; select 1 is
a common, readable convention.
This is a good pattern for "has any" or "has none" questions. You avoid accidental row multiplication because the outer query returns one row per outer row, not one row per match.
select p.parent_name
from parents as p
where exists (
select 1
from children as c
where c.parent_id = p.parent_id
) Connect the subquery to the outer row
Most EXISTS checks are correlated: the inner query refers to
the current row from the outer query. In this lesson, each customer row is
tested against orders for that same customer_id.
Schema · Garden Shop Tables · orders, customers 2 tables
One row per order. Unshipped orders have a null shipped_date.
One row per customer. Some customers have no phone on file.
Show customers who have placed at least one order and have
no cancelled orders. Return first_name and
last_name, sorted by last name and first name.
Run your query to inspect the result.
Expected answer
- Columns: first_name, last_name.
- Rows: 15 customers who have ordered and have no cancelled orders.
- EXISTS and NOT EXISTS only check whether matching rows are present.
Related
INNER, LEFT, RIGHT, FULL, and CROSS joins.
Join types and common join patterns.
Practice join keys, left joins, duplicate rows, and debugging.
One-to-many joins can inflate totals.
Qualify shared columns with a table alias.
Nested SELECTs, IN, EXISTS, and correlation.