Exists in SubQuery
Exists in SubQuery
how to use the Oracle EXISTS operator to test for the existence of rows.
SELECT
*
FROM
table_name
WHERE
EXISTS(subquery);
Code language: SQL (Structured Query Language) (sql)
The EXISTS operator returns true if the subquery returns any rows, otherwise, it
returns false. In addition, the EXISTS operator terminates the processing of the
subquery once the subquery returns the first row.
See the following customers and orders tables in the sample database:
The following example uses the EXISTS operator to find all customers who have the
order.
SELECT
name
FROM
customers c
WHERE
EXISTS (
SELECT
1
FROM
orders
WHERE
customer_id = c.customer_id
)
ORDER BY
name;
Code language: SQL (Structured Query Language) (sql)
For each customer in the customers table, the subquery checks whether the customer
appears on the orders table. If yes, then the EXISTS operator returns true and stops
scanning the orders table. Otherwise, the EXISTS operator returns false if the subquery
does not find the customer in the orders table.
The result if the EXISTS operator is used by the WHERE clause to retrieve the
customer that makes the subquery returns any rows.
Note that Oracle ignores the select list in the subquery so you can use any column,
literal value, expression, etc. In the query above, we used literal number 1.
UPDATE
warehouses w
SET
warehouse_name = warehouse_name || ', USA'
WHERE
EXISTS (
SELECT
1
FROM
locations
WHERE
country_id = 'US'
AND location_id = w.location_id
);
Code language: SQL (Structured Query Language) (sql)
For each warehouse, the subquery checks whether its location is in the US or not. If
yes, the EXISTS operator in the WHERE clause returns true that causes the outer query
append the string ', USA' to the warehouse name. Otherwise, the UPDATE statement
does nothing due to the condition is the WHERE clause is false.
SELECT
warehouse_name
FROM
warehouses
INNER JOIN locations
USING(location_id)
WHERE
country_id = 'US';
Code language: SQL (Structured Query Language) (sql)
Suppose, we have to send special appreciation emails to all customers who had
orders in 2016. To do this, first, we create a new table to store the data of customers:
Then, we insert customers who had orders in 2016 into the customers_2016 table:
INSERT
INTO
customers_2016(
company,
first_name,
last_name,
email
) SELECT
name company,
first_name,
last_name,
email
FROM
customers c
INNER JOIN contacts ON
contacts.customer_id = c.customer_id
WHERE
EXISTS(
SELECT
*
FROM
orders
WHERE
customer_id = c.customer_id
AND EXTRACT(
YEAR
FROM
order_date
)
ORDER BY
company;
Code language: SQL (Structured Query Language) (sql)
The following statement retrieves data from the customers_2016 table to verify the
insert:
Oracle EXISTS vs. IN
The EXISTS operator stops scanning rows once the subquery returns the first row
because it can determine the result whereas the IN operator must scan all rows
returned by the subquery to conclude the result.
In addition, the IN clause can’t compare anything with NULL values, but
the EXISTS clause can compare everything with NULL values. For example, the first
statement returns no row while the second one returns all rows from
the customers table:
SELECT
*
FROM
customers
WHERE
customer_id IN(NULL);
SELECT
*
FROM
customers
WHERE
EXISTS (
SELECT
NULL
FROM
dual
);
Code language: SQL (Structured Query Language) (sql)
Typically, the EXISTS operator is faster than IN operator when the result set of the
subquery is large. By contrast, the IN operator is faster than EXISTS operator when the
result set of the subquery is small.