What are the main differences between NOT IN vs NOT EXISTS in SQL?

  • How-Tos FAQs
  • December 16, 2018
Supercharge Your Snowflake SQL
with Datameer's
Data Transformation

The SQL operator NOT IN and NOT EXISTS may seem similar at first glance, but there are differences between them.

Let us set up the tables ‘orders’ and ‘order_details’ as below:

CREATE TABLE orders (
    order_id INT,
    customer_name VARCHAR(100),
    order_date DATETIME,
    total_orders INT
);

INSERT INTO  orders
SELECT 1, 'Jack', '2020-02-03', 4 UNION ALL
SELECT 2, 'Rose', '2020-01-09', 19 UNION ALL
SELECT 3, 'Jack', '2020-02-03', 40 UNION ALL
SELECT 4, 'Rose', '2020-01-09', NULL ;

CREATE TABLE order_details (
    order_detail_id INT,
    order_id VARCHAR(100),
    Item VARCHAR(100),
    item_desc VARCHAR(200)
);

INSERT INTO  order_details
SELECT 1, 1, 'laptop', NULL UNION ALL
SELECT 2, 2, 'mouse', 'Optical Mouse' UNION ALL
SELECT 3, 3, 'headphone', NULL UNION ALL
SELECT 4, 4, 'pendrive', '64 GB';

The main disadvantage of NOT IN is that it does not support NULL value. Even if only a single value in the given data is NULL, the whole result will be empty. This is why NOT IN can be unpredictable and hence advised to avoid using if there is the NULL value or there is the possibility of having a NULL value in the future.

SELECT * FROM orders o
WHERE o.customer_name NOT IN ('Jack', NULL);



#Output
Returns nothing

NOT EXISTS can handle the NULL value. In fact, it does not care what data is selected in the subquery. The subquery only returns TRUE or False. It returns TRUE if it returns any row and returns FALSE if it does not return any row.

SELECT * FROM orders o
WHERE EXISTS (

               SELECT od.item_desc
              FROM order_details od
              WHERE od.order_id = o.order_id
              AND o.total_orders <5
              );
#Output
# order_id      customer_name       order_date      total_orders
--------------------------------------------------------------------------
1           Jack           2020-02-03 00:00:00     4

NOT IN can be used to compare a column with some hardcoded value, but it is not possible to use hardcoded values in NOT EXISTS.

-- Valid Query
SELECT * FROM customers
WHERE customer_name NOT IN ('Jack');

#Output

# customers_id     customer_name  email
-----------------------------------------------------------------
2              Jully                       jack@email.com
3              John                      john@email.com
4              Rose              rose@email.com

-- Invalid Query

SELECT * FROM customers
WHERE NOT EXISTS ('Jack');

#Output
ERROR

Up Next:

Read What are the main differences between UNION and UNION ALL in SQL?

Related Posts

SQL FAQ Feat

How to avoid SQL injection in PHP?

  • How-Tos FAQs
  • December 15, 2018