UNION & UNION ALL
Learn how to combine the results of two or more SELECT queries into a single result set using UNION and UNION ALL.
Introduction
So far, every query you have written has produced results from a single SELECT statement. But sometimes you need to combine the results of two separate SELECT queries into one list — for example, merging "current students" and "alumni" into a single combined roster.
This is exactly what the UNION and UNION ALL operators are for. They stack the results of two or more queries on top of each other, producing one final result set.
- What UNION does and how it removes duplicate rows.
- What UNION ALL does and why it is faster.
- The rules both queries must follow to be combined.
- A worked example combining two related tables.
- How to sort a combined result set.
What is UNION?
UNION combines the result sets of two or more SELECT statements into a single result set, stacking the rows from the second query underneath the rows from the first. By default, UNION also removes any duplicate rows from the combined output.
SELECT column1, column2 FROM table1
UNION
SELECT column1, column2 FROM table2;Imagine printing the results of the first query, then printing the results of the second query directly underneath — UNION glues those two lists into one, and then removes any exact-duplicate rows.
Column Rules
UNION does not work on just any two queries — both SELECT statements must be "union-compatible":
- Both queries must return the same number of columns.
- The columns must be in the same order.
- The data types of matching columns must be compatible (for example, both text, or both numeric).
- The column names shown in the final result come from the first SELECT statement.
If the two queries return a different number of columns, MySQL raises an error immediately: "The used SELECT statements have a different number of columns."
Worked Example: Students and Alumni
Suppose a school keeps two separate tables: "students" for people currently enrolled, and "alumni" for people who have graduated. A newsletter needs one combined list of every name and email, past and present.
CREATE TABLE students (
id INT PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100)
);
CREATE TABLE alumni (
id INT PRIMARY KEY,
full_name VARCHAR(50),
contact_email VARCHAR(100)
);
INSERT INTO students VALUES
(1, 'Alex', 'alex@school.com'),
(2, 'Priya', 'priya@school.com');
INSERT INTO alumni VALUES
(1, 'Sam', 'sam@alumni.com'),
(2, 'Priya', 'priya@school.com');Notice that "Priya" appears in both tables with the exact same email — a realistic scenario if a student's record was copied over after graduation. Now combine both lists with UNION:
SELECT name, email FROM students
UNION
SELECT full_name, contact_email FROM alumni;+-------+---------------------+
| name | email |
+-------+---------------------+
| Alex | alex@school.com |
| Priya | priya@school.com |
| Sam | sam@alumni.com |
+-------+---------------------+Even though "Priya" existed in both source tables, she appears only once in the final result — UNION automatically removed the duplicate row.
UNION ALL
UNION ALL combines result sets exactly like UNION, but it keeps every row, including exact duplicates. Because it skips the extra step of scanning for and removing duplicates, UNION ALL is generally faster than UNION, especially on large result sets.
SELECT name, email FROM students
UNION ALL
SELECT full_name, contact_email FROM alumni;+-------+---------------------+
| name | email |
+-------+---------------------+
| Alex | alex@school.com |
| Priya | priya@school.com |
| Sam | sam@alumni.com |
| Priya | priya@school.com |
+-------+---------------------+This time "Priya" shows up twice, once from each table, because UNION ALL does not check for or remove duplicates.
UNION vs UNION ALL
| Aspect | UNION | UNION ALL |
|---|---|---|
| Duplicate rows | Removed automatically | Kept as-is |
| Performance | Slower (must compare rows) | Faster (no comparison step) |
| Best used when | You need a clean, distinct list | You know there are no duplicates, or duplicates are fine/expected |
If you are not sure whether duplicates matter for your use case, and performance is a concern, prefer UNION ALL unless you specifically need deduplication — it is the cheaper operation.
Ordering Combined Results
An ORDER BY clause used with UNION applies to the entire combined result set, and must go at the very end — after the last SELECT statement, not attached to an individual query.
SELECT name, email FROM students
UNION
SELECT full_name, contact_email FROM alumni
ORDER BY name;+-------+---------------------+
| name | email |
+-------+---------------------+
| Alex | alex@school.com |
| Priya | priya@school.com |
| Sam | sam@alumni.com |
+-------+---------------------+Common Mistakes
- Trying to UNION queries with a different number of columns.
- Assuming UNION ALL removes duplicates — it does not.
- Using UNION when UNION ALL would work and perform better, because you actually know there are no overlapping rows.
- Attaching ORDER BY to the first SELECT statement instead of the very end of the whole UNION.
Best Practices
- Reach for UNION ALL by default unless you specifically need deduplication.
- Make sure both SELECT statements list columns in a matching, deliberate order.
- Add a literal label column (e.g. SELECT 'student' AS source) when you need to tell which original table a combined row came from.
- Keep ORDER BY at the end of the entire UNION statement.
Frequently Asked Questions
Can I combine more than two SELECT statements?
Yes. You can chain as many SELECT statements together with UNION or UNION ALL as needed, as long as every one of them follows the same column rules.
Do the column names have to match exactly between queries?
No, only the number of columns and their compatible data types matter. The final result set uses the column names from the very first SELECT statement.
Can I use WHERE, GROUP BY, or JOIN inside each SELECT in a UNION?
Yes. Each individual SELECT statement can have its own WHERE, GROUP BY, JOIN, and other clauses — only ORDER BY has to move to the very end of the whole UNION.
Is UNION the same as a JOIN?
No. A JOIN combines columns from two tables side by side into wider rows. UNION combines rows from two queries vertically, stacking them into one taller result set.
Key Takeaways
- UNION combines the results of two or more SELECT queries into one result set.
- UNION removes duplicate rows; UNION ALL keeps every row, including duplicates.
- UNION ALL is generally faster because it skips the deduplication step.
- Both queries in a UNION must return the same number of columns with compatible types.
- ORDER BY applies to the whole combined result and belongs at the very end.
Summary
UNION and UNION ALL let you merge the results of multiple SELECT queries into a single, unified result set — useful whenever related data is split across tables, such as current students and alumni.
In this lesson, you learned the difference between UNION and UNION ALL, the column-matching rules they require, and how to sort a combined result. Next, you will learn about views — saved queries that behave like virtual tables.
- You can combine two SELECT queries with UNION.
- You understand when to use UNION ALL instead.
- You know the column-matching rules UNION requires.
- You are ready to learn about views.