How to implement Common Table Expressions in PostgreSQL?

Common Table Expressions (CTEs) provide a way to define temporary named result sets within a SQL statement in PostgreSQL. CTEs are useful for breaking down complex queries into smaller, more manageable parts and can be referenced multiple times within a query. Let’s explore how to implement CTEs in PostgreSQL with real-life data set examples:

Syntax of a CTE:

The syntax of a CTE in PostgreSQL is as follows:

WITH cte_name (column1, column2, …) AS (
SELECT column1, column2, …
FROM table_name
WHERE condition
)
SELECT *
FROM cte_name

The CTE is defined within the WITH clause and given a name (cte_name). The CTE can reference columns from the underlying table and include filtering conditions as needed. The result of the CTE is then used in subsequent parts of the query.

Real-Life Example:

Let’s consider a real-life example where we have a table named orders that contains information about customer orders. We want to find the total order amount for each customer by calculating the sum of their orders. Here’s how you can use a CTE to achieve this:

WITH customer_orders AS (
SELECT customer_id, SUM(order_amount) AS total_amount
FROM orders
GROUP BY customer_id
)
SELECT customer_id, total_amount
FROM customer_orders;

In the above example, the CTE named customer_orders calculates the total order amount for each customer using the SUM aggregation function. The CTE is then referenced in the main query to retrieve the customer ID and total order amount.

Recursive CTEs:

PostgreSQL also supports recursive CTEs, which allow you to perform recursive operations on hierarchical data structures. Recursive CTEs are useful for tasks like hierarchical queries, tree traversals, and graph traversals.

Here’s an example of a recursive CTE that traverses a hierarchical table named employees to retrieve the employee hierarchy from a given starting point:

WITH RECURSIVE employee_hierarchy AS (
SELECT employee_id, employee_name, manager_id, 1 AS level
FROM employees
WHERE employee_id = 1 — Starting employee ID
UNION ALL
SELECT e.employee_id, e.employee_name, e.manager_id, eh.level + 1
FROM employees e
JOIN employee_hierarchy eh ON e.manager_id = eh.employee_id
)
SELECT employee_id, employee_name, level
FROM employee_hierarchy
ORDER BY level, employee_id;

In this example, the recursive CTE employee_hierarchy starts with a base query that retrieves the information for the starting employee. The recursive part then joins the employees table with the CTE itself to traverse the hierarchical structure recursively. The final query retrieves the employee ID, name, and level of each employee in the hierarchy.

Common Table Expressions provide a powerful way to break down complex queries into manageable parts and improve query readability. They can be used for various purposes, including data transformation, filtering, aggregation, and recursive operations. By using CTEs, you can write more organized and modular queries in PostgreSQL.

About Shiv Iyer 443 Articles
Open Source Database Systems Engineer with a deep understanding of Optimizer Internals, Performance Engineering, Scalability and Data SRE. Shiv currently is the Founder, Investor, Board Member and CEO of multiple Database Systems Infrastructure Operations companies in the Transaction Processing Computing and ColumnStores ecosystem. He is also a frequent speaker in open source software conferences globally.