PostgreSQL WITH Clause (Common Table Expressions)
What is WITH?
The WITH clause, also known as Common Table Expressions (CTEs), allows you to define temporary named result sets that can be referenced within a SELECT, INSERT, UPDATE, or DELETE statement. CTEs make complex queries more readable and maintainable.
Basic Syntax
Simple CTE Examples
Example 1: Basic CTE
Example 2: CTE with Aggregation
Multiple CTEs
You can define multiple CTEs in a single query:
Recursive CTEs
Recursive CTEs allow you to query hierarchical or tree-structured data:
Basic Recursive CTE Syntax
Example 1: Number Sequence
Example 2: Employee Hierarchy
Example 3: Category Tree
CTE with INSERT, UPDATE, DELETE
CTE with INSERT
CTE with UPDATE
CTE with DELETE
Practical Examples
Example 1: Sales Analysis
Example 2: Customer Segmentation
Example 3: Running Totals
Performance Considerations
1. Materialized CTEs
By default, CTEs are optimization fences. Use MATERIALIZED or NOT MATERIALIZED:
2. When to Use CTEs
CTEs are best for:
- Improving query readability
- Recursive queries
- Multiple references to the same subquery
- Breaking down complex logic
3. Performance Tips
Advanced Patterns
Pattern 1: Data Deduplication
Pattern 2: Gap Analysis
Pattern 3: Pivot Data
Common Mistakes and Solutions
Mistake 1: Infinite Recursion
Mistake 2: Referencing CTE Before Definition
Mistake 3: Unnecessary Complexity
Best Practices
- Use Descriptive Names: Name CTEs clearly to indicate their purpose
- Break Down Complex Queries: Use multiple CTEs for readability
- Consider Performance: Use MATERIALIZED/NOT MATERIALIZED when appropriate
- Limit Recursion Depth: Always include termination conditions
- Document Complex Logic: Add comments for complex recursive CTEs
- Test Recursive CTEs: Verify termination and correctness
- Use for Readability: CTEs excel at making queries more maintainable
Summary
WITH clauses (CTEs) are powerful tools for query organization:
- Define temporary named result sets
- Improve query readability and maintainability
- Support recursive queries for hierarchical data
- Can be used with SELECT, INSERT, UPDATE, DELETE
- Multiple CTEs can be defined in a single query
- MATERIALIZED/NOT MATERIALIZED controls optimization
- Essential for complex data transformations and analysis
Mastering CTEs is crucial for writing clean, maintainable PostgreSQL queries.