UNION

Learn how to use the PostgreSQL UNION and UNION ALL operators to combine result sets from multiple SELECT queries, with examples and key rules.

5 min read · Last updated: March 2026 · Back to overview

Quick Answer

The PostgreSQL UNION operator combines the result sets of two or more SELECT statements into a single result set and removes duplicate rows. Use UNION ALL to keep duplicates, which is faster because it skips the deduplication step.

Spin up a Postgres database in 20 seconds with Vela.

Try Vela Sandbox

The UNION operator combines the result sets of two or more SELECT queries into a single result set. By default, UNION removes duplicate rows. Use UNION ALL to retain duplicates — it is faster because no deduplication step is performed.

UNION syntax and rules

SELECT select_list FROM A
UNION
SELECT select_list FROM B;

Both queries must follow these rules:

  • The same number of columns in the same order.
  • Compatible data types for each corresponding column pair.
  • ORDER BY, if needed, goes after the final query only.

To sort the combined result:

SELECT select_list FROM A
UNION
SELECT select_list FROM B
ORDER BY sort_expression;

UNION vs UNION ALL examples

Given two tables, top_rated_films and most_popular_films, both sharing The Godfather and The Dark Knight:

-- UNION removes duplicates (6 rows instead of 8)
SELECT * FROM top_rated_films
UNION
SELECT * FROM most_popular_films;
          title          | release_year
-------------------------+--------------
 An American Pickle      |         2020
 The Dark Knight         |         2008
 Greyhound               |         2020
 The Shawshank Redemption|         1994
 The Godfather           |         1972
 12 Angry Men            |         1957
(6 rows)
-- UNION ALL keeps all rows including duplicates (8 rows)
SELECT * FROM top_rated_films
UNION ALL
SELECT * FROM most_popular_films;
          title          | release_year
-------------------------+--------------
 The Shawshank Redemption|         1994
 The Godfather           |         1972
 The Dark Knight         |         2008
 12 Angry Men            |         1957
 An American Pickle      |         2020
 The Godfather           |         1972
 The Dark Knight         |         2008
 Greyhound               |         2020
(8 rows)

UNION ALL with ORDER BY

To sort the combined result, add ORDER BY after the last query:

SELECT * FROM top_rated_films
UNION ALL
SELECT * FROM most_popular_films
ORDER BY title;
          title          | release_year
-------------------------+--------------
 12 Angry Men            |         1957
 An American Pickle      |         2020
 Greyhound               |         2020
 The Dark Knight         |         2008
 The Dark Knight         |         2008
 The Godfather           |         1972
 The Godfather           |         1972
 The Shawshank Redemption|         1994
(8 rows)

Key tips for using UNION

  • Prefer UNION ALL over UNION when you know the component queries return distinct rows — it avoids an expensive sort-and-deduplicate step on large result sets.
  • Column names in the output come from the first SELECT. Use aliases in the first query to control output column names.
  • You cannot place ORDER BY, LIMIT, or FETCH inside individual component queries — only after the final query in the chain.
  • When combining queries from different schemas or sources, ensure data types are compatible or use explicit CAST to avoid type mismatch errors.
  • For comparing which rows appear in both result sets, use INTERSECT instead of UNION.

Reference: PostgreSQL documentation — Combining Queries (UNION, INTERSECT, EXCEPT).

Continue in Set Operations: INTERSECT.

Related in this section: INTERSECT · EXCEPT

Frequently Asked Questions

What is the difference between UNION and UNION ALL in PostgreSQL?

UNION combines result sets and removes duplicate rows, performing an implicit DISTINCT on the combined output. UNION ALL combines result sets and keeps all rows, including duplicates. UNION ALL is faster because it does not need to sort and deduplicate the results. Use UNION when duplicates are not meaningful; use UNION ALL when you know the queries return distinct rows or when you deliberately want all rows (e.g., audit log aggregation).

What are the rules for using UNION in PostgreSQL?

Both SELECT statements must return the same number of columns in the same order. The data types of corresponding columns must be compatible (PostgreSQL will attempt implicit casting). Column names in the final result are taken from the first SELECT statement. NULL values are allowed in any position. You cannot use ORDER BY, LIMIT, or FETCH in individual SELECT statements within a UNION — only after the final query.

Can I use ORDER BY with UNION in PostgreSQL?

Yes, but only as a single ORDER BY clause placed after the last SELECT statement in the UNION. PostgreSQL will raise an error if you put ORDER BY inside an individual component query. The ORDER BY applies to the final combined result set and can reference column names or positional numbers from the first SELECT.

When should I use UNION vs a JOIN?

Use UNION to stack rows from multiple queries vertically — the result combines rows where each query contributes similar types of records (e.g., customers from two tables, events from two sources). Use JOIN to combine columns horizontally — connecting related data from multiple tables in the same row. UNION requires compatible column structures; JOIN requires a matching key.

How does UNION handle NULL values?

UNION treats two NULL values as equal for deduplication purposes. If both queries return a row where all columns are NULL, UNION will keep only one such row. This differs from NULLs in a WHERE clause or JOIN condition, where NULL = NULL is false. UNION ALL does not deduplicate, so multiple NULL rows are always preserved.