SQL
CTEs
CTEs make complex logic readable and modular.
Basic CTE
WITH active_accounts AS (
SELECT * FROM account WHERE status = 'OPEN'
)
SELECT product_code, COUNT(*) AS n
FROM active_accounts
GROUP BY product_code;Chained CTEs: Waterfall Pattern
WITH step1_open AS (
SELECT * FROM account WHERE account_status = 'OPEN'
),
step2_has_balance AS (
SELECT * FROM step1_open WHERE current_balance > 0
),
step3_min_limit AS (
SELECT * FROM step2_has_balance WHERE credit_limit >= 2000
),
step4_tenure AS (
SELECT * FROM step3_min_limit
WHERE open_date <= CURRENT_DATE - INTERVAL '6 months'
)
SELECT 'All open accounts' AS step, COUNT(*) AS n FROM step1_open
UNION ALL
SELECT 'Has balance > 0', COUNT(*) FROM step2_has_balance
UNION ALL
SELECT 'Limit >= 2000', COUNT(*) FROM step3_min_limit
UNION ALL
SELECT 'Open 6+ months', COUNT(*) FROM step4_tenure;Compute -> Classify -> Summarize
WITH account_activity AS (
SELECT
account_id,
COUNT(txn_id) AS txn_count,
COALESCE(SUM(amount), 0) AS total_spend
FROM transactions
WHERE txn_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY account_id
),
classified AS (
SELECT *,
CASE
WHEN total_spend >= 5000 THEN 'HIGH_VALUE'
WHEN total_spend >= 1000 THEN 'MEDIUM_VALUE'
WHEN total_spend > 0 THEN 'LOW_VALUE'
ELSE 'ZERO_SPEND'
END AS segment
FROM account_activity
)
SELECT
segment,
COUNT(*) AS accounts,
ROUND(AVG(total_spend), 2) AS avg_spend,
ROUND(AVG(txn_count), 1) AS avg_txns
FROM classified
GROUP BY segment;Recursive CTEs
WITH RECURSIVE hierarchy AS (
SELECT
employee_id, employee_name, manager_id,
employee_name AS path,
1 AS level
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT
e.employee_id, e.employee_name, e.manager_id,
h.path || ' > ' || e.employee_name,
h.level + 1
FROM employees e
INNER JOIN hierarchy h ON e.manager_id = h.employee_id
)
SELECT * FROM hierarchy ORDER BY path;CTE vs Subquery vs Temp Table
| Approach | When to use |
|---|---|
| CTE | Readability and multi-step logic |
| Subquery | Small one-off filter/scalar use |
| Temp table | Reuse expensive intermediate results and index them |