SQL Practice Logo

SQLPractice Online

Window Functions vs CTEs: Concept

Module: Subqueries & CTEs

Window functions and CTEs are fundamentally different tools that people often confuse because both can work with aggregates. Window functions perform calculations across a set of rows related to the current row, while keeping all rows in the result. CTEs organize queries into named, reusable chunks. The key difference: Window functions are about WHAT you calculate (row-level analytics), CTEs are about HOW you structure your query (organization). You can use both together - CTE to prep data, window function to analyze it. Understanding this distinction prevents performance disasters.

**

**Window Functions: Row-Level Analytics**

Window functions calculate values for each row based on a "window" of related rows. Key characteristic: They don't reduce row count.

```sql

-- Every employee gets their department's average salary

SELECT

name,

salary,

AVG(salary) OVER (PARTITION BY department) as dept_avg

FROM employees;

-- Result: Same number of rows as input

-- Each row has its own dept_avg value

```

Common use cases:

1. **Rankings**: RANK(), DENSE_RANK(), ROW_NUMBER()

2. **Running totals**: SUM() OVER (ORDER BY date)

3. **Moving averages**: AVG() OVER (ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)

4. **Percentiles**: PERCENTILE_CONT() OVER ()

5. **Lead/Lag**: Compare current row with previous/next rows

**CTEs: Query Organization**

CTEs break complex queries into named, readable steps. Key characteristic: They organize query structure.

```sql

-- Break complex query into steps

WITH active_customers AS (

SELECT customer_id, signup_date

FROM customers

WHERE status = 'active'

),

recent_orders AS (

SELECT customer_id, COUNT(*) as order_count

FROM orders

WHERE order_date >= CURRENT_DATE - INTERVAL '30 days'

GROUP BY customer_id

)

SELECT

ac.customer_id,

ac.signup_date,

COALESCE(ro.order_count, 0) as recent_orders

FROM active_customers ac