How to Use CTEs in Redshift

Galaxy Glossary

How do you write and use a CTE in Redshift?

A Common Table Expression (CTE) lets you create a temporary, named result set you can reference multiple times within a single Redshift query.

Sign up for the latest in SQL knowledge from the Galaxy Team!
Welcome to the Galaxy, Guardian!
Oops! Something went wrong while submitting the form.

Description

What problem do CTEs solve in Redshift?

CTEs replace nested sub-queries with readable, reusable result sets. You define them once, then reference them like regular tables in the same statement.

How does the WITH keyword work?

WITH introduces one or more CTEs. Each CTE has a name, an optional column list, and a SELECT that builds its data. Subsequent SELECT, INSERT, UPDATE, or DELETE statements can reference the CTEs.

Can I chain multiple CTEs?

Yes. Separate CTE definitions with commas.Later CTEs can reference earlier ones, enabling step-by-step transformations.

Why prefer CTEs over temporary tables?

CTEs live only for the duration of the statement, require no clean-up, and avoid catalog bloat.They also make complex queries self-contained and easier to version-control.

What is the basic CTE workflow?

1) Write WITH cte_name AS (SELECT ...) 2) Add more CTEs if needed 3) Finish with a main query that refers to them.

Example: calculating customer lifetime value

The example below shows two CTEs: recent_orders and customer_ltv.The final SELECT joins them to the Customers table.

WITH recent_orders AS (
SELECT customer_id, SUM(total_amount) AS last_90_days
FROM Orders
WHERE order_date >= CURRENT_DATE - INTERVAL '90 day'
GROUP BY customer_id
),
customer_ltv AS (
SELECT o.customer_id, SUM(o.total_amount) AS lifetime_value
FROM Orders o
GROUP BY o.customer_id
)
SELECT c.id, c.name, clv.lifetime_value, ro.last_90_days
FROM Customers c
LEFT JOIN customer_ltv clv ON clv.customer_id = c.id
LEFT JOIN recent_orders ro ON ro.customer_id = c.id;

Best practices for Redshift CTEs?

Keep CTEs small; Redshift materializes each CTE, so avoid SELECT *.Index with DISTKEY/SORTKEY on underlying tables to speed joins. Use ANALYZE to keep stats fresh.

When should you avoid CTEs?

Use derived tables or temp tables when the same interim result is needed across multiple statements, or when the CTE would duplicate large data sets several times within a single query.

.

Why How to Use CTEs in Redshift is important

How to Use CTEs in Redshift Example Usage


WITH popular_products AS (
    SELECT oi.product_id, SUM(oi.quantity) AS units_sold
    FROM OrderItems oi
    GROUP BY oi.product_id
    HAVING SUM(oi.quantity) > 500
),
stock_status AS (
    SELECT p.id, p.stock, CASE WHEN p.stock < 100 THEN 'LOW' ELSE 'OK' END AS stock_flag
    FROM Products p
)
SELECT p.name, pp.units_sold, ss.stock_flag
FROM popular_products pp
JOIN Products p   ON p.id = pp.product_id
JOIN stock_status ss ON ss.id = p.id
ORDER BY pp.units_sold DESC;

How to Use CTEs in Redshift Syntax


WITH cte_name [ ( column1 [, ... ] ) ] AS (
    SELECT ...            -- build interim result
)
[, other_cte AS ( ... )]
<main_statement>; -- SELECT | INSERT | UPDATE | DELETE

-- Example in ecommerce context
WITH high_value_customers AS (
    SELECT customer_id, SUM(total_amount) AS total_spent
    FROM Orders
    GROUP BY customer_id
    HAVING SUM(total_amount) > 1000
),
latest_purchase AS (
    SELECT o.customer_id, MAX(o.order_date) AS last_order
    FROM Orders o
    GROUP BY o.customer_id
)
SELECT c.id, c.name, hvc.total_spent, lp.last_order
FROM Customers c
JOIN high_value_customers hvc ON hvc.customer_id = c.id
JOIN latest_purchase lp      ON lp.customer_id  = c.id;

Common Mistakes

Frequently Asked Questions (FAQs)

Does a CTE persist after the query?

No. A CTE exists only for the duration of the statement that defines it.

Can a CTE reference another CTE?

Yes. Define the referenced CTE earlier in the WITH clause.

Are CTEs indexed?

CTEs are materialized in working memory; they do not have indexes. Performance depends on the underlying table keys and statistics.

Want to learn about other SQL terms?

Trusted by top engineers on high-velocity teams
Aryeo Logo
Assort Health
Curri
Rubie
BauHealth Logo
Truvideo Logo
Welcome to the Galaxy, Guardian!
Oops! Something went wrong while submitting the form.