PostgreSQL IN

Match values against a list of options

📋 What is PostgreSQL IN?

The IN operator checks if a value matches any value in a list. It's a shorthand for multiple OR conditions, making queries cleaner and easier to read. Perfect for filtering by multiple specific values like cities, categories, or IDs.


-- Find customers from specific cities
SELECT name FROM customers
WHERE city IN ('New York', 'London', 'Tokyo');
                                    

IN Operator Patterns

📝

Basic IN

Match against list of values

WHERE status IN ('Active', 'Pending')
🔢

IN with Numbers

Match numeric values

WHERE id IN (1, 5, 10, 15)
🚫

NOT IN

Exclude values from list

WHERE country NOT IN ('USA', 'Canada')
🔍

IN with Subquery

Match against query results

WHERE id IN (SELECT user_id FROM orders)

🔹 Basic IN Operator

The IN operator simplifies queries by replacing multiple OR conditions with a single list. Instead of writing multiple OR statements, you list all values in parentheses. This makes code more readable and maintainable, especially when checking against many values. Works with any data type including text, numbers, and dates.

-- Sample data: employees table
-- emp_id | name          | department
-- 1      | John Smith    | Sales
-- 2      | Jane Doe      | IT
-- 3      | Mike Johnson  | HR
-- 4      | Sarah Wilson  | Sales

-- Find employees in Sales or IT departments
SELECT name, department FROM employees
WHERE department IN ('Sales', 'IT');

Output:

name department
John Smith Sales
Jane Doe IT
Sarah Wilson Sales

🔹 IN vs Multiple OR

The IN operator is cleaner and more efficient than writing multiple OR conditions. Both produce the same results, but IN is shorter and easier to understand. When you have many values to check, IN significantly reduces code length and improves readability, making maintenance easier for you and your team.

-- Using OR (longer, harder to read)
SELECT * FROM products
WHERE category = 'Electronics' 
   OR category = 'Computers' 
   OR category = 'Phones';

-- Using IN (cleaner, easier to read)
SELECT * FROM products
WHERE category IN ('Electronics', 'Computers', 'Phones');

Both queries return the same results:

✅ Same output, but IN is more concise!

🔹 IN with Numeric Values

The IN operator works perfectly with numeric data types including integers, decimals, and floating-point numbers. You don't need quotes around numbers in the list. This is useful for filtering by specific IDs, quantities, prices, or any numeric criteria where you need to match exact values.

-- Find products with specific IDs
SELECT product_name, price FROM products
WHERE product_id IN (101, 105, 110, 115);

Output:

product_name price
Laptop 1200
Mouse 25
Monitor 300

🔹 NOT IN Operator

Use NOT IN to exclude specific values from your results. It returns all rows where the column value doesn't match any value in the list. This is useful for filtering out test data, inactive records, or specific categories you want to exclude from analysis or reports.

-- Find customers NOT from these cities
SELECT name, city FROM customers
WHERE city NOT IN ('New York', 'Los Angeles', 'Chicago');

Output:

name city
John Smith Boston
Sarah Wilson Seattle

🔹 IN with Subquery

Combine IN with a subquery to match values against results from another query. The subquery runs first and returns a list of values, then IN checks if the column matches any of those values. This is powerful for complex filtering based on related data from other tables.

-- Find customers who have placed orders
SELECT name FROM customers
WHERE customer_id IN (
    SELECT DISTINCT customer_id 
    FROM orders
);

Output:

name
John Smith
Jane Doe
Mike Johnson

🔹 IN with Multiple Conditions

Combine IN with other WHERE conditions using AND or OR for complex filtering. The IN operator can be part of larger conditional logic, allowing you to create sophisticated queries. This gives you flexibility to filter data based on multiple criteria simultaneously, making your queries more powerful and precise.

-- Find high-value orders from specific regions
SELECT order_id, region, amount FROM orders
WHERE region IN ('North', 'South', 'East')
  AND amount > 1000;

Output:

order_id region amount
101 North 1500
105 East 2000

💡 Important Notes:

  • IN is more readable than multiple OR conditions
  • Works with any data type: text, numbers, dates
  • Use NOT IN to exclude values from results
  • Can combine with subqueries for dynamic lists
  • NULL values in the list are ignored
  • Be careful with NOT IN and NULL values - may produce unexpected results

🧠 Test Your Knowledge

What is the main advantage of IN over multiple OR conditions?