Academic Block

SQL EXISTS
Learn how to check whether a subquery returns one or more rows using the SQL EXISTS operator.

What is the EXISTS Operator?

The EXISTS operator checks whether a subquery returns at least one row. If the subquery returns one or more rows, EXISTS evaluates to true. If it returns no rows, EXISTS evaluates to false.

Basic EXISTS Syntax

EXISTS is normally used with a subquery inside a WHERE clause. The subquery determines whether matching records exist in another table.

DROP TABLE IF EXISTS customers;
DROP TABLE IF EXISTS orders;

CREATE TABLE customers (
  customer_id INTEGER,
  customer_name TEXT
);

CREATE TABLE orders (
  order_id INTEGER,
  customer_id INTEGER,
  amount INTEGER
);

INSERT INTO customers VALUES
  (1, 'Aarav'),
  (2, 'Meera'),
  (3, 'Kabir'),
  (4, 'Riya');

INSERT INTO orders VALUES
  (101, 1, 900),
  (102, 1, 1200),
  (103, 3, 700);

SELECT customer_id, customer_name
FROM customers AS c
WHERE EXISTS (
  SELECT 1
  FROM orders AS o
  WHERE o.customer_id = c.customer_id
)
ORDER BY customer_id;

EXISTS with a WHERE Condition

The subquery can contain additional conditions. In this example, only customers with an order greater than 1000 are returned.

DROP TABLE IF EXISTS customers;
DROP TABLE IF EXISTS purchases;

CREATE TABLE customers (
  customer_id INTEGER,
  customer_name TEXT
);

CREATE TABLE purchases (
  purchase_id INTEGER,
  customer_id INTEGER,
  amount INTEGER
);

INSERT INTO customers VALUES
  (1, 'Nisha'),
  (2, 'Rohan'),
  (3, 'Tara'),
  (4, 'Dev');

INSERT INTO purchases VALUES
  (201, 1, 450),
  (202, 1, 1500),
  (203, 2, 600),
  (204, 3, 2200);

SELECT customer_id, customer_name
FROM customers AS c
WHERE EXISTS (
  SELECT 1
  FROM purchases AS p
  WHERE p.customer_id = c.customer_id
    AND p.amount > 1000
)
ORDER BY customer_id;

EXISTS with Employee Records

EXISTS can be used to find employees who have related records in another table.

DROP TABLE IF EXISTS employees;
DROP TABLE IF EXISTS projects;

CREATE TABLE employees (
  employee_id INTEGER,
  employee_name TEXT,
  department TEXT
);

CREATE TABLE projects (
  project_id INTEGER,
  employee_id INTEGER,
  project_name TEXT
);

INSERT INTO employees VALUES
  (1, 'Anaya', 'Design'),
  (2, 'Vikram', 'Engineering'),
  (3, 'Mira', 'Marketing'),
  (4, 'Karan', 'Finance');

INSERT INTO projects VALUES
  (501, 1, 'Website Redesign'),
  (502, 2, 'Mobile App'),
  (503, 2, 'API Upgrade');

SELECT employee_id, employee_name, department
FROM employees AS e
WHERE EXISTS (
  SELECT 1
  FROM projects AS p
  WHERE p.employee_id = e.employee_id
)
ORDER BY employee_id;

NOT EXISTS

NOT EXISTS returns true when the subquery returns no rows. It is useful for finding records that do not have a related record.

DROP TABLE IF EXISTS customers;
DROP TABLE IF EXISTS orders;

CREATE TABLE customers (
  customer_id INTEGER,
  customer_name TEXT
);

CREATE TABLE orders (
  order_id INTEGER,
  customer_id INTEGER,
  amount INTEGER
);

INSERT INTO customers VALUES
  (1, 'Ishita'),
  (2, 'Arjun'),
  (3, 'Neha'),
  (4, 'Dev');

INSERT INTO orders VALUES
  (301, 1, 800),
  (302, 2, 1200);

SELECT customer_id, customer_name
FROM customers AS c
WHERE NOT EXISTS (
  SELECT 1
  FROM orders AS o
  WHERE o.customer_id = c.customer_id
)
ORDER BY customer_id;

EXISTS with Multiple Conditions

Multiple conditions can be used inside an EXISTS subquery with AND and other SQL operators.

DROP TABLE IF EXISTS products;
DROP TABLE IF EXISTS sales;

CREATE TABLE products (
  product_id INTEGER,
  product_name TEXT,
  category TEXT
);

CREATE TABLE sales (
  sale_id INTEGER,
  product_id INTEGER,
  quantity INTEGER
);

INSERT INTO products VALUES
  (1, 'Keyboard', 'Accessories'),
  (2, 'Monitor', 'Displays'),
  (3, 'Mouse', 'Accessories'),
  (4, 'Webcam', 'Accessories');

INSERT INTO sales VALUES
  (401, 1, 5),
  (402, 2, 2),
  (403, 3, 12);

SELECT product_id, product_name
FROM products AS p
WHERE EXISTS (
  SELECT 1
  FROM sales AS s
  WHERE s.product_id = p.product_id
    AND s.quantity >= 10
)
ORDER BY product_id;

EXISTS with Different Tables

EXISTS can check whether related data is available in another table, even when the two tables contain different types of information.

DROP TABLE IF EXISTS authors;
DROP TABLE IF EXISTS books;

CREATE TABLE authors (
  author_id INTEGER,
  author_name TEXT
);

CREATE TABLE books (
  book_id INTEGER,
  author_id INTEGER,
  title TEXT
);

INSERT INTO authors VALUES
  (1, 'Aditi Rao'),
  (2, 'Kunal Shah'),
  (3, 'Meera Das'),
  (4, 'Ravi Sen');

INSERT INTO books VALUES
  (601, 1, 'Learning SQL'),
  (602, 3, 'Database Basics');

SELECT author_id, author_name
FROM authors AS a
WHERE EXISTS (
  SELECT 1
  FROM books AS b
  WHERE b.author_id = a.author_id
)
ORDER BY author_id;

EXISTS with a Subquery and Date Values

EXISTS can also be used when the related records must satisfy a date condition. SQLite stores dates commonly as text in ISO format such as YYYY-MM-DD.

DROP TABLE IF EXISTS customers;
DROP TABLE IF EXISTS visits;

CREATE TABLE customers (
  customer_id INTEGER,
  customer_name TEXT
);

CREATE TABLE visits (
  visit_id INTEGER,
  customer_id INTEGER,
  visit_date TEXT
);

INSERT INTO customers VALUES
  (1, 'Sana'),
  (2, 'Ravi'),
  (3, 'Tina'),
  (4, 'Mohan');

INSERT INTO visits VALUES
  (701, 1, '2026-07-10'),
  (702, 2, '2026-06-15'),
  (703, 3, '2026-08-05');

SELECT customer_id, customer_name
FROM customers AS c
WHERE EXISTS (
  SELECT 1
  FROM visits AS v
  WHERE v.customer_id = c.customer_id
    AND v.visit_date >= '2026-08-01'
)
ORDER BY customer_id;

EXISTS with UPDATE

EXISTS can also be used inside an UPDATE statement to modify rows only when related records are found.

DROP TABLE IF EXISTS employees;
DROP TABLE IF EXISTS bonuses;

CREATE TABLE employees (
  employee_id INTEGER,
  employee_name TEXT,
  status TEXT
);

CREATE TABLE bonuses (
  bonus_id INTEGER,
  employee_id INTEGER,
  amount INTEGER
);

INSERT INTO employees VALUES
  (1, 'Aarav', 'Regular'),
  (2, 'Meera', 'Regular'),
  (3, 'Kabir', 'Regular');

INSERT INTO bonuses VALUES
  (801, 1, 5000),
  (802, 3, 3000);

UPDATE employees
SET status = 'Bonus Eligible'
WHERE EXISTS (
  SELECT 1
  FROM bonuses AS b
  WHERE b.employee_id = employees.employee_id
);

SELECT employee_id, employee_name, status
FROM employees
ORDER BY employee_id;

EXISTS with DELETE

EXISTS can also be used with DELETE to remove rows when a related record exists in another table.

DROP TABLE IF EXISTS customers;
DROP TABLE IF EXISTS inactive_accounts;

CREATE TABLE customers (
  customer_id INTEGER,
  customer_name TEXT
);

CREATE TABLE inactive_accounts (
  customer_id INTEGER
);

INSERT INTO customers VALUES
  (1, 'Nikhil'),
  (2, 'Pooja'),
  (3, 'Tanya'),
  (4, 'Dev');

INSERT INTO inactive_accounts VALUES
  (2),
  (4);

DELETE FROM customers
WHERE EXISTS (
  SELECT 1
  FROM inactive_accounts AS i
  WHERE i.customer_id = customers.customer_id
);

SELECT customer_id, customer_name
FROM customers
ORDER BY customer_id;

EXISTS vs IN

Feature EXISTS IN
Main purpose Checks whether rows exist Checks whether a value belongs to a set
Commonly uses Correlated subqueries Lists or subqueries
Example EXISTS (SELECT 1 …) id IN (SELECT id …)

EXISTS vs NOT EXISTS

Operator Result Common Use
EXISTS True when the subquery returns at least one row Find records with related data
NOT EXISTS True when the subquery returns no rows Find records without related data

Advantages of EXISTS

  • Checks whether related records exist.
  • Works well with correlated subqueries.
  • Can be combined with multiple conditions.
  • Supports both EXISTS and NOT EXISTS logic.
  • Can be used with SELECT, UPDATE, and DELETE statements.

Best Practices

  • Use EXISTS when you only need to know whether a related row exists.
  • Use NOT EXISTS when you need records without a matching row.
  • Use table aliases to make correlated subqueries easier to understand.
  • Use SELECT 1 inside EXISTS when the actual selected value is not needed.
  • For repeatable SQLite examples, use DROP TABLE IF EXISTS before creating tables.

The EXISTS operator is used to determine whether a subquery returns at least one row. Together with NOT EXISTS, it provides a powerful way to find records that do or do not have related data.

Ctrl + Enter to run SQL code Esc to close editor

🧪 Test Your SQL Code

Edit the SQL code on the left and click “Run Code” to see the result on the right.

📝 SQL Code
👁️ Preview (query result)

Click “Run Code” to see the result here.