SQL Practice Logo

SQLPractice Online

Window Functions vs CTEs: Mistakes

Module: Subqueries & CTEs

-- Using CTE with correlated subquery for running total

WITH running_totals AS (

SELECT

order_date,

amount,

(SELECT SUM(amount)

FROM orders o2

WHERE o2.order_date <= o1.order_date

) as running_total

FROM orders o1

)

SELECT * FROM running_totals;

-- Performance: 45 seconds for 1M rows

-- Complexity: O(N²) - scans all previous rows for each row

-- Use window function for running total

SELECT

order_date,

amount,

SUM(amount) OVER (ORDER BY order_date) as running_total

FROM orders;

-- Performance: 0.4 seconds for 1M rows

-- Complexity: O(N log N) - sorts once, accumulates in single pass

Correlated subqueries for running totals are O(N²) - for each row, they scan all previous rows. Window functions are specifically optimized for this with O(N log N) complexity. The database sorts data once, then accumulates values in a single pass. For 1M rows, correlated subquery does 500 billion comparisons vs window function doing 20 million. Always use window functions for running totals, cumulative sums, and moving averages.

Use SUM() OVER (ORDER BY ...) for running totals. Never use correlated subqueries.

Critical

Query takes 45 seconds instead of 0.4 seconds. 100x slower!

-- Using CTE with COUNT subquery for ranking

WITH ranked_employees AS (

SELECT

employee_id,

name,

department,

salary,

(SELECT COUNT(*)

FROM employees e2

WHERE e2.department = e1.department

AND e2.salary > e1.salary

) + 1 as dept_rank

FROM employees e1

)