sqlcmd.net validated sql reference
intermediate joining MySQL MariaDB SQL Server PostgreSQL SQLite

Find Rows With No Match Using An Anti-Join

Return rows from one table that have no corresponding row in a second table using a LEFT JOIN with a NULL check.

Docker-validated Not currently validation-green

Find customers who have never placed an order

Alice has two orders and Carol has one, so only Bob — who has no orders at all — appears in the result. The LEFT JOIN produces a row for every customer including those with no orders; for unmatched customers the orders columns are all NULL. The WHERE o.customer_id IS NULL filter then keeps only those unmatched rows. Prefer this pattern over NOT IN (SELECT ...) because NOT IN returns no rows at all if any value in the subquery is NULL.

Rows loaded before the example query runs.
Setup
CREATE TABLE customers (id INT, name VARCHAR(50));

CREATE TABLE orders (id INT, customer_id INT, amount INT);

INSERT INTO
  customers (id, name)
VALUES
  (1, 'Alice'),
  (2, 'Bob'),
  (3, 'Carol');

INSERT INTO
  orders (id, customer_id, amount)
VALUES
  (1, 1, 100),
  (2, 1, 250),
  (3, 3, 75);
Shared across supported engines.
SQL
SELECT
  c.id,
  c.name
FROM
  customers c
  LEFT JOIN orders o ON c.id = o.customer_id
WHERE
  o.customer_id IS NULL
ORDER BY
  c.id;
Returned rows for the shared example.
idname
2Bob

The SQL is identical across all supported engines.

Where this command helps.

  • finding customers who have never placed an order
  • identifying products that have never been sold
  • detecting rows in one table that are missing from a reference table

What the command is doing.

An anti-join returns rows from the left table that have no matching row in the right table. The standard SQL pattern is a LEFT JOIN filtered by WHERE right_table.key IS NULL. This is often clearer and more portable than NOT IN (which behaves unexpectedly when NULLs are present in the subquery) or NOT EXISTS. All major SQL engines support the LEFT JOIN ... WHERE IS NULL anti-join pattern with identical syntax.