Basics
- How to Insert
- How to Update
- How to Delete
- How to Trim Strings
- How to Use substring()
- How to Use substring() with RegEx to Extract a String
- How to Replace Substrings
- How to Modify Arrays
- How to Compare Arrays
- How to Concatenate Strings
- How to Convert the Case of a String
- How to Create an Array
- How to Insert Data Into an Array
- How to Query Arrays
- How to Use string_agg()
Database Management
- How to Create a Table
- How to Drop a Table
- How to Rename a Table
- How to Truncate a Table
- How to Duplicate a Table
- How to Add a Column
- How to Change a Column Name
- How to Add a Default Value
- How to Remove a Default Value From a Column
- How to Add a Not Null Constraint
- How to Remove a Not Null Constraint
- How to Add an Index
- How to Drop an Index
- How to Create a View
- How to Drop a View
- How to Reset Sequence
- How to Drop a Column
Dates and Times
Analysis
- How to Use nullif()
- How to Use Lateral Joins
- How to Calculate Percentiles
- How to Get the First Row per Group
- How to Use generate_series to Avoid Gaps in Data
- How to Do Type Casting
- How to Write a Common Table Expression
- How to Import a CSV using Copy
- How to Compare Two Values When One Is Null
- How to Use Coalesce
- How to Write a Case Statement
- How to Use Filter to Have Multiple Counts
- How to Calculate Cumulative Sum-Running Total
- How to Query a JSON Column
How to Write a Common Table Expression in PostgreSQL
Common Table Expressions (CTEs) are a powerful feature in PostgreSQL that allow you to write cleaner and more modular SQL queries. This tutorial will guide you through what CTEs are, when to use them, and how to write them effectively.
What is a Common Table Expression?
A Common Table Expression (CTE) is a temporary result set that you can reference within a SQL statement. Think of it as creating a temporary table that only exists during the execution of that query. It helps make complex queries easier to read, maintain, and debug.
Basic Syntax
WITH cte_name AS ( SELECT column1, column2 FROM some_table WHERE condition ) SELECT * FROM cte_name;
The WITH
clause defines the CTE. You can then reference cte_name
as if it were a table in your subsequent query.
Example: Simple CTE
WITH recent_orders AS ( SELECT id, customer_id, order_date FROM orders WHERE order_date > CURRENT_DATE - INTERVAL '30 days' ) SELECT customer_id, COUNT(*) FROM recent_orders GROUP BY customer_id;
Here, we first select orders from the last 30 days into the recent_orders
CTE, then we count how many orders each customer placed.
Chaining Multiple CTEs
WITH recent_orders AS ( SELECT id, customer_id, order_date FROM orders WHERE order_date > CURRENT_DATE - INTERVAL '30 days' ), customer_totals AS ( SELECT customer_id, COUNT(*) AS total_orders FROM recent_orders GROUP BY customer_id ) SELECT c.customer_id, c.total_orders, u.name FROM customer_totals c JOIN users u ON c.customer_id = u.id;
You can chain multiple CTEs together to build modular query blocks.
When to Use CTEs
- To break down complex queries into manageable pieces
- To improve readability and maintainability
- When you need to reference the same subquery multiple times
- To use recursion (for hierarchical or tree-like data)
Tips and Best Practices
- Give your CTEs meaningful names to improve readability.
- Limit the number of CTEs in a single query to avoid confusion.
- Be aware of performance—sometimes materialized views or subqueries can be faster for large datasets.
Conclusion
Common Table Expressions are an excellent tool in PostgreSQL for simplifying and structuring your SQL queries. By using CTEs, you can write more modular, understandable, and maintainable SQL. Give them a try in your next query!