UNION
UNION
The UNION operator combines the result sets of two or more SELECT statements into a single result set. By default, UNION removes duplicate rows from the combined result.
-- Combine customer names from US and UK customers
SELECT customer_name, email, 'US' AS country
FROM customers_us
UNION
SELECT customer_name, email, 'UK' AS country
FROM customers_uk;
Rules for UNION:
- All SELECT statements must have the same number of columns
- Corresponding columns must have compatible data types
- The ORDER BY clause can only appear at the end
- Column names come from the first SELECT statement
-- Combine products from multiple sources
SELECT product_name, price, 'Electronics' AS category
FROM electronics_products
UNION
SELECT product_name, price, 'Clothing' AS category
FROM clothing_products
ORDER BY product_name;
UNION performs a DISTINCT operation internally to remove duplicates, which requires sorting and comparison. This makes it slower than UNION ALL. Use UNION only when you genuinely need to eliminate duplicates. For large datasets, UNION ALL is significantly faster.
UNION ALL
UNION ALL
UNION ALL combines result sets like UNION but keeps all rows, including duplicates. It does not perform the deduplication step, making it much faster.
-- Combine all orders from 2024 and 2025 (duplicates are fine)
SELECT order_id, order_date, total_amount
FROM orders_2024
UNION ALL
SELECT order_id, order_date, total_amount
FROM orders_2025
ORDER BY order_date;
Since UNION ALL skips deduplication, it is the preferred choice when:
- You know there are no duplicates
- Duplicates are acceptable in the result
- Performance is critical
- You are combining data from different time periods or sources
-- Combine sales from all regions for a report
SELECT 'North' AS region, product_id, amount FROM sales_north
UNION ALL
SELECT 'South' AS region, product_id, amount FROM sales_south
UNION ALL
SELECT 'East' AS region, product_id, amount FROM sales_east
UNION ALL
SELECT 'West' AS region, product_id, amount FROM sales_west;
A common mistake is using UNION when UNION ALL would suffice. Always ask yourself: do I actually need deduplication? If the answer is no, use UNION ALL for better performance.
INTERSECT
INTERSECT
INTERSECT returns only the rows that appear in both result sets. Like UNION, it removes duplicates by default.
-- Find customers who placed orders in both 2024 and 2025
SELECT customer_id FROM orders WHERE YEAR(order_date) = 2024
INTERSECT
SELECT customer_id FROM orders WHERE YEAR(order_date) = 2025;
INTERSECT is useful for finding common elements between two datasets. The column count and types must match, just like with UNION.
-- Find products that appear in both the electronics and bestseller lists
SELECT product_id, product_name FROM electronics_catalog
INTERSECT
SELECT product_id, product_name FROM bestsellers;
Not all databases support INTERSECT. In MySQL, you can simulate it using INNER JOIN or EXISTS:
-- MySQL equivalent of INTERSECT
SELECT DISTINCT a.customer_id
FROM orders a
INNER JOIN orders b ON a.customer_id = b.customer_id
WHERE YEAR(a.order_date) = 2024 AND YEAR(b.order_date) = 2025;
INTERSECT is conceptually similar to an INNER JOIN between two queries, but the syntax is cleaner for pure set operations.
EXCEPT / MINUS
EXCEPT / MINUS
EXCEPT (or MINUS in Oracle) returns rows from the first query that do not appear in the second query. It is the set difference operation.
-- Find customers who ordered in 2024 but NOT in 2025
SELECT customer_id FROM orders WHERE YEAR(order_date) = 2024
EXCEPT
SELECT customer_id FROM orders WHERE YEAR(order_date) = 2025;
EXCEPT removes duplicates by default. Use EXCEPT ALL to keep duplicates (supported in PostgreSQL and SQL Server).
-- Find products in the catalog that are out of stock
SELECT product_id, product_name FROM products
EXCEPT
SELECT p.product_id, p.product_name
FROM products p
JOIN inventory i ON p.product_id = i.product_id
WHERE i.quantity > 0;
The order of queries matters with EXCEPT. A EXCEPT B is different from B EXCEPT A:
-- Customers in 2024 but not 2025
SELECT customer_id FROM orders WHERE YEAR(order_date) = 2024
EXCEPT
SELECT customer_id FROM orders WHERE YEAR(order_date) = 2025;
-- Customers in 2025 but not 2024
SELECT customer_id FROM orders WHERE YEAR(order_date) = 2025
EXCEPT
SELECT customer_id FROM orders WHERE YEAR(order_date) = 2024;
EXCEPT is commonly used for data reconciliation, finding missing records, and comparing snapshots of data across different time periods.
Practice Problems
Write a query to combine email addresses from both customers and employees into a single list without duplicates.
Solution
SELECT email FROM customers
UNION
SELECT email FROM employees;Write a query to find customers who placed orders in both January 2025 AND February 2025 using INTERSECT.
Solution
SELECT customer_id FROM orders WHERE order_date >= '2025-01-01' AND order_date < '2025-02-01'
INTERSECT
SELECT customer_id FROM orders WHERE order_date >= '2025-02-01' AND order_date < '2025-03-01';Write a query to find products that exist in the catalog but have never been ordered. Use EXCEPT.
Solution
SELECT product_id FROM products
EXCEPT
SELECT DISTINCT product_id FROM order_items;Quiz
1. What is the difference between UNION and UNION ALL?
2. What must be true about the SELECT statements in a UNION?
3. Which operator returns rows that appear in both result sets?
4. What is the primary purpose of SQL UNION?
Flashcards
Question
What is the difference between UNION and UNION ALL?
Click to reveal answer
Answer
UNION removes duplicate rows from the combined result. UNION ALL keeps all rows including duplicates and is faster because it skips deduplication.
Question
What does INTERSECT return?
Click to reveal answer
Answer
Only the rows that appear in both result sets. It is the set intersection operation, similar to an INNER JOIN between two queries.
Question
What is the difference between EXCEPT and MINUS?
Click to reveal answer
Answer
They are the same operation (set difference) with different names. EXCEPT is used in SQL Server, PostgreSQL, and MySQL. MINUS is used in Oracle.
Question
What is SQL UNION?
Click to reveal answer
Answer
SQL UNION is a key concept in SQL databases.
Question
When to use SQL UNION?
Click to reveal answer
Answer
Use SQL UNION when building production systems that require reliability, scalability, and maintainability.
Revision Notes
Key Takeaways
- 1.UNION removes duplicates; UNION ALL is faster and keeps them
- 2.All SELECT statements must have matching column counts and types
- 3.INTERSECT finds common rows; EXCEPT finds differences
- 4.Always prefer UNION ALL unless deduplication is required
Interview Tips
- •Know when to use UNION ALL over UNION for performance
- •Explain how to simulate INTERSECT and EXCEPT in MySQL
- •Discuss the order of queries in EXCEPT (A EXCEPT B vs B EXCEPT A)
- •Mention column compatibility requirements for set operations
Cheat Sheet
UNION & Set Operations Cheat Sheet
UNION vs UNION ALL
SELECT col FROM t1 UNION SELECT col FROM t2; -- removes duplicates
SELECT col FROM t1 UNION ALL SELECT col FROM t2; -- keeps duplicates
INTERSECT
SELECT customer_id FROM orders_2024
INTERSECT
SELECT customer_id FROM orders_2025;
EXCEPT
SELECT customer_id FROM orders_2024
EXCEPT
SELECT customer_id FROM orders_2025;
Rules
- Same number of columns in all queries
- Compatible data types for corresponding columns
- ORDER BY only at the very end
- Column names from the first SELECT