The SQL EXISTS operator is mostly used to test whether a subquery returns rows. It returns TRUE if rows exists in the subquery and FALSE if they do not.
The EXISTS condition is used in combination with a subquery. It returns TRUE whenever the subquery returns one or more values.
In its simplest form the syntax for the SQL EXISTS condition is
WHERE EXISTS (sub query)
Suppose we need to return all sales orders written by salespeople with sales year to date greater than three million dollars. To do so we can use the EXISTS clause as shown in this example:
SELECT SalesOrderID, RevisionNumber, OrderDate FROM Sales.SalesOrderHeader WHERE EXISTS (SELECT 1 FROM sales.SalesPerson WHERE SalesYTD > 3000000 AND SalesOrderHeader.SalesPersonID = Sales.SalesPerson.BusinessEntityID)
When this SQL executes the following comparisons are made:
- The WHERE clause returns all records where the EXISTS clause is TRUE.
- The EXIST clause uses a correlated subquery. The outer query is correlated to the inner query by SalesPersonID.
- Only SalesPersons with SalesYTD greater than three million are included in the results.
- The EXISTS clause returns TRUE if one or more rows are returned by the subquery.
The EXISTS condition is a membership condition in the sense it only returns TRUE if a result is returned.
SQL NOT EXISTS
Conversely, if we want to test for non-membership we can use NOT EXISTS.
NOT EXISTS returns TRUE if zero rows are returned. So, if we want to find all sales orders that were written by salespeople that didn’t have 3,000,000 in year-to-date sales, we can use the following query:
SELECT SalesOrderID, RevisionNumber, OrderDate FROM Sales.SalesOrderHeader WHERE NOT EXISTS (SELECT 1 FROM sales.SalesPerson WHERE SalesYTD > 3000000 AND SalesOrderHeader.SalesPersonID = Sales.SalesPerson.BusinessEntityID)
WHAT happens to NULL?
When the subquery returns a NULL what does EXIST return: NULL, TRUE, or FALSE?
To be honest I was surprised.
I was sure it would return NULL, but to my surprise, I learned it returns TRUE. Therefore, if your subquery returns a NULL value, the SQL EXISTS statement resolves to TRUE. In the following example all the SalesOrderHeader rows are returned as the WHERE clause essentially resolved to TRUE:
SELECT SalesOrderID, RevisionNumber, OrderDate FROM Sales.SalesOrderHeader WHERE EXISTS (SELECT NULL)
As we study the IN operator, we’ll see this behavior is unique to the EXISTS clause.
What to read next:
Can you help me please?
I have a subquery in the where clause which gives back the name of a column, but the SQL doesn’t recognize the result. So when I run the query it returns an empty table.
The code looks like this:
SELECT * FROM projects where (SELECT CONCAT(“`p_”,id,”`”) from properties where id in (select SUBSTRING_INDEX(SUBSTRING_INDEX(ids, ‘,’, numbers.n), ‘,’, -1) from (select 1 n union all select 2 union all select 3 union all select 4 union all select 5) numbers INNER JOIN filters_properties on CHAR_LENGTH(ids) -CHAR_LENGTH(REPLACE(ids, ‘,’, ”))>=numbers.n-1 WHERE filter_id = (SELECT id FROM filters WHERE name = ‘GYMS’))) = 1;
Another problem: when the subquery returns more than 1 row, I don’t know what to do with it. How can I separate them to get a result like (p_1 = 1 or p_2 = 1 or p_3 = 1)?
Hi Kris, suggestion…
This format of compound elements in the where clause and sub-queries has been useful to me over the years. It’s rare to see it in documentation. If you decide to revise the blog post, think about including examples like this.
(field1, field2) in ( (1, 125788 ), (1, 127753), (1, 301852) )
Of course, instead of specific values on the right side of the “in”, you can have a subquery that returns the same number of values.
That is a great suggestion. I’ll follow you up on that!
This was helpful to me. Thanks.
Hi Kris, I need to check a date column in a subquery for any nulls and return a boolean to use in the outer query. How would you do this? where would you place the subquery in the where, from, select? Any help would be greatly appreciated.
Is the data column part of a larger query, or are you just trying to check for the data column in the main query’s current row?
Can you show an example output?
Thank you, this was very helpful!
I’m glad you find the site helpful. Come back soon!