5 min read
•Question 16 of 29mediumWhat are CTEs (Common Table Expressions)?
Temporary named result sets.
What You'll Learn
- What CTEs are
- Basic and recursive CTEs
- Benefits over subqueries
What is a CTE?
A CTE is a temporary named result set that exists within the scope of a single statement.
Basic CTE
query.sqlSQL
WITH active_users AS (
SELECT id, name, email
FROM users
WHERE status = 'active'
)
SELECT * FROM active_users WHERE name LIKE 'J%';Multiple CTEs
query.sqlSQL
WITH
active_users AS (
SELECT * FROM users WHERE status = 'active'
),
user_orders AS (
SELECT user_id, COUNT(*) as order_count, SUM(total) as total_spent
FROM orders
GROUP BY user_id
)
SELECT
u.name,
uo.order_count,
uo.total_spent
FROM active_users u
JOIN user_orders uo ON u.id = uo.user_id
ORDER BY uo.total_spent DESC;Recursive CTE
query.sqlSQL
-- Employee hierarchy
WITH RECURSIVE emp_hierarchy AS (
-- Base case: top-level managers
SELECT id, name, manager_id, 0 AS level
FROM employees
WHERE manager_id IS NULL
UNION ALL
-- Recursive case: employees with managers
SELECT e.id, e.name, e.manager_id, h.level + 1
FROM employees e
JOIN emp_hierarchy h ON e.manager_id = h.id
)
SELECT * FROM emp_hierarchy ORDER BY level, name;
-- Generate number series
WITH RECURSIVE numbers AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1 FROM numbers WHERE n < 10
)
SELECT * FROM numbers;CTE vs Subquery
query.sqlSQL
-- CTE (more readable)
WITH order_totals AS (
SELECT user_id, SUM(total) as total_spent
FROM orders GROUP BY user_id
)
SELECT * FROM users u
JOIN order_totals ot ON u.id = ot.user_id;
-- Subquery (harder to read)
SELECT * FROM users u
JOIN (
SELECT user_id, SUM(total) as total_spent
FROM orders GROUP BY user_id
) ot ON u.id = ot.user_id;