MySQL UNION

Combining results from multiple queries

🔗 What is UNION?

UNION combines result sets from two or more SELECT statements into a single result set, automatically removing duplicate rows. All SELECT statements must have the same number of columns with compatible data types.


-- Simple UNION example
SELECT name FROM customers
UNION
SELECT name FROM suppliers;
                                    

Output:

name
John Smith
ABC Corp
Jane Doe
XYZ Ltd

Key UNION Concepts

🚫

Removes Duplicates

Automatically eliminates duplicate rows

SELECT id FROM table1
UNION
SELECT id FROM table2;
📊

Same Columns

All queries must have equal columns

SELECT col1, col2
UNION
SELECT col1, col2;
🔤

Compatible Types

Column data types must match

-- Both must be strings or numbers
SELECT name, age UNION ...
📋

First Query Names

Column names from first SELECT used

SELECT name AS full_name
UNION SELECT customer_name;

🔹 Basic UNION Syntax

UNION combines multiple SELECT statements vertically, stacking results on top of each other. Each SELECT must return the same number of columns with compatible data types. The column names from the first SELECT statement are used in the final result set.

-- Basic UNION syntax
SELECT column1, column2 FROM table1
UNION
SELECT column1, column2 FROM table2;

-- UNION with multiple queries
SELECT name, city FROM customers
UNION
SELECT name, city FROM suppliers
UNION
SELECT name, city FROM partners;

Example Result:

Combined results with duplicates removed

🔹 Practical UNION Example

Let's combine customer and supplier contact information into a single directory. This demonstrates how UNION merges data from different sources while maintaining data integrity by removing duplicate entries, creating a unified contact list for business operations.

-- Create sample tables
CREATE TABLE customers (
    id INT,
    name VARCHAR(100),
    email VARCHAR(100),
    type VARCHAR(50)
);

CREATE TABLE suppliers (
    id INT,
    company_name VARCHAR(100),
    contact_email VARCHAR(100),
    category VARCHAR(50)
);

-- Insert sample data
INSERT INTO customers VALUES
(1, 'John Smith', '[email protected]', 'Retail'),
(2, 'Jane Doe', '[email protected]', 'Wholesale');

INSERT INTO suppliers VALUES
(1, 'ABC Corp', '[email protected]', 'Materials'),
(2, 'John Smith', '[email protected]', 'Parts');

-- UNION to create unified contact list
SELECT 
    name AS contact_name,
    email,
    'Customer' AS source
FROM customers
UNION
SELECT 
    company_name,
    contact_email,
    'Supplier' AS source
FROM suppliers
ORDER BY contact_name;

Output:

contact_name email source
ABC Corp [email protected] Supplier
Jane Doe [email protected] Customer
John Smith [email protected] Customer

Note: Duplicate "John Smith" removed by UNION

🔹 UNION with WHERE and ORDER BY

You can filter individual SELECT statements with WHERE clauses before combining them with UNION. The ORDER BY clause must be placed at the end of the entire UNION query to sort the final combined result set, not individual queries.

-- UNION with filtering
SELECT product_name, price, 'Electronics' AS category
FROM electronics
WHERE price > 100
UNION
SELECT product_name, price, 'Furniture' AS category
FROM furniture
WHERE price > 100
ORDER BY price DESC;

-- UNION with conditions
SELECT employee_name, department
FROM employees
WHERE status = 'Active'
UNION
SELECT contractor_name, assigned_dept
FROM contractors
WHERE contract_end > CURDATE()
ORDER BY employee_name;

Output:

Filtered and sorted combined results

🔹 Real-World Use Cases

UNION is perfect for consolidating data from multiple sources into unified reports. Common applications include creating master contact lists from customers and vendors, combining current and archived records for historical analysis, merging product catalogs from different warehouses, and generating comprehensive reports from departmental databases.

-- Use Case 1: Combine current and archived orders
SELECT order_id, customer_name, order_date, 'Current' AS status
FROM current_orders
WHERE order_date >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
UNION
SELECT order_id, customer_name, order_date, 'Archived' AS status
FROM archived_orders
WHERE order_date >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
ORDER BY order_date DESC;

-- Use Case 2: Create unified product search
SELECT product_id, product_name, price, 'In Stock' AS availability
FROM warehouse_a
UNION
SELECT product_id, product_name, price, 'In Stock' AS availability
FROM warehouse_b
ORDER BY product_name;

🧠 Test Your Knowledge

What does UNION do with duplicate rows?