SQL EXISTS Operator for Beginners

In SQL, the EXISTS operator specifies a subquery to test for the existence of rows. It returns TRUE when the subquery returns one or more rows.

A subquery is a query that is nested inside another query (or even another subquery)

This article contains some basic examples of the EXISTS operator.

Source Tables

The following tables are used for the examples on this page.

SELECT * FROM PetTypes;
SELECT * FROM Pets;

Result:

+-------------+-----------+
| PetTypeId   | PetType   |
|-------------+-----------|
| 1           | Bird      |
| 2           | Cat       |
| 3           | Dog       |
| 4           | Rabbit    |
+-------------+-----------+
(4 rows affected)
+---------+-------------+-----------+-----------+------------+
| PetId   | PetTypeId   | OwnerId   | PetName   | DOB        |
|---------+-------------+-----------+-----------+------------|
| 1       | 2           | 3         | Fluffy    | 2020-11-20 |
| 2       | 3           | 3         | Fetch     | 2019-08-16 |
| 3       | 2           | 2         | Scratch   | 2018-10-01 |
| 4       | 3           | 3         | Wag       | 2020-03-15 |
| 5       | 1           | 1         | Tweet     | 2020-11-28 |
| 6       | 3           | 4         | Fluffy    | 2020-09-17 |
| 7       | 3           | 2         | Bark      | NULL       |
| 8       | 2           | 4         | Meow      | NULL       |
+---------+-------------+-----------+-----------+------------+
(8 rows affected)

Example

Here’s an example to demonstrate the EXISTS operator.

SELECT 
    pt.PetTypeId,
    pt.PetType
FROM PetTypes pt
WHERE EXISTS ( 
    SELECT p.PetTypeId 
    FROM Pets p 
    WHERE p.PetTypeId = pt.PetTypeId 
    );

Result:

+-------------+-----------+
| PetTypeId   | PetType   |
|-------------+-----------|
| 1           | Bird      |
| 2           | Cat       |
| 3           | Dog       |
+-------------+-----------+

This example shows us how many pet types are in our pet hotel. There are actually four pet types, but only three of those match with an actual pet in the Pets table.

This provides the same result that we would have gotten with the following query that uses the IN operator.

SELECT 
    PetTypeId,
    PetType
FROM PetTypes
WHERE PetTypeId IN ( SELECT PetTypeId FROM Pets );

Using NOT EXISTS

We could add the NOT operator to negate the results and see how many pet types are not in our pet hotel.

SELECT 
    pt.PetTypeId,
    pt.PetType
FROM PetTypes pt
WHERE NOT EXISTS ( 
    SELECT p.PetTypeId 
    FROM Pets p 
    WHERE p.PetTypeId = pt.PetTypeId 
    );

Result:

+-------------+-----------+
| PetTypeId   | PetType   |
|-------------+-----------|
| 4           | Rabbit    |
+-------------+-----------+

In this case, our database contains a pet type of Rabbit, but we don’t currently have any rabbits as pets.