PostgreSQL Common Table Expressions (CTEs): A Powerful Tool for Complex Queries
Doug Ortiz ??
??Cloud | ???DevOps | ??Postgres | ???Databases | ??K8s | ???Podcaster | ??AI | ??Machine Learning | ??Tech Challenges? Let's Talk! | ??Solving Impossible Projects | ??Instructor | ??Automating Success | ??DevRel
PostgreSQL Common Table Expressions (CTEs): A Powerful Tool for Complex Queries
Introduction
Common Table Expressions (CTEs) are a powerful feature in PostgreSQL that allow you to define temporary named subqueries within a larger query. CTEs can be used to simplify complex queries, make them more readable and reusable, and improve performance.
Benefits of using CTEs
There are many benefits to using CTEs in PostgreSQL, including:
Syntax
The syntax for CTEs in PostgreSQL is as follows:
SQL
WITH cte_name (column_list) AS (
? cte_query
)
SELECT ...
FROM cte_name
The WITH clause is used to introduce the CTE. The cte_name is the name of the CTE, and the column_list is the list of columns that the CTE will return. The cte_query is the subquery that defines the CTE. The SELECT statement in the main query then refers to the CTE by name.
Examples
Here are some examples of how to use CTEs in PostgreSQL:
Calculate running totals:
SQL
WITH running_totals AS (
? SELECT
??? customer_id,
??? SUM(order_amount) AS running_total
? FROM orders
? GROUP BY customer_id
? ORDER BY order_date
)
?
SELECT
? customer_id,
? running_total
FROM running_totals
This CTE calculates the running total of order amounts for each customer. The main query then selects the customer ID and running total from the CTE.
Rank rows:
SQL
WITH ranked_rows AS (
? SELECT
??? customer_id,
??? RANK() OVER (PARTITION BY product_id ORDER BY order_amount DESC) AS rank
? FROM orders
)
?
领英推荐
SELECT
?customer_id,
? rank
FROM ranked_rows
This CTE ranks the customers for each product by order amount, from highest to lowest. The main query then selects the customer ID and rank from the CTE.
Filter data:
SQL
WITH filtered_data AS (
? SELECT
??? *
? FROM orders
? WHERE order_date >= CURRENT_DATE - INTERVAL '1 MONTH'
)
?
SELECT
? *
FROM filtered_data
This CTE filters the orders table to only include orders that were placed in the past month. The main query then selects all rows from the filtered table.
Recursive CTEs
Recursive CTEs allow you to write queries that can traverse hierarchical data structures, such as a tree or graph. For example, the following CTE can be used to recursively calculate the total number of descendants of each node in a tree:
SQL
WITH recursive descendants AS (
? SELECT
??? node_id,
??? COUNT(*) AS descendant_count
? FROM tree
? GROUP BY node_id
? UNION ALL
? SELECT
??? tree.parent_id,
??? descendant_count + 1
? FROM tree
? JOIN descendants ON tree.node_id = descendants.descendant_id
)
?
SELECT
? node_id,
? descendant_count
FROM descendants
This CTE works by first calculating the number of direct descendants for each node in the tree. Then, it recursively adds the number of descendants of each descendant to the total number of descendants for the parent node.
Conclusion
CTEs are a powerful tool that can be used to simplify complex queries, make them more readable and reusable, and improve performance. If you are writing complex SQL queries in PostgreSQL, I encourage you to learn more about CTEs. They can be a valuable addition to your SQL toolbox.
#Database #SQL #DataAnalysis #CTEs #CareerGrowth #postgres