Advanced

Window Functions

Perform calculations across sets of rows related to the current row without collapsing them - essential for ranking, running totals, and time-series analysis.

What Are Window Functions?

Window functions compute values across a set of rows (a "window") while keeping every individual row in the result. Unlike GROUP BY, they do not collapse rows.

SQL - Syntax
function_name(args) OVER (
  PARTITION BY column1, column2   -- optional: divide into groups
  ORDER BY column3               -- optional: define row order
  ROWS BETWEEN ...               -- optional: frame specification
)

Ranking Functions

SQL
SELECT name, category, price,
  ROW_NUMBER() OVER (ORDER BY price DESC) AS row_num,
  RANK()       OVER (ORDER BY price DESC) AS rank,
  DENSE_RANK() OVER (ORDER BY price DESC) AS dense_rank
FROM products;
FunctionTiesGapsExample: prices 100, 90, 90, 80
ROW_NUMBER()Breaks ties arbitrarilyNo1, 2, 3, 4
RANK()Same rank for tiesYes1, 2, 2, 4
DENSE_RANK()Same rank for tiesNo1, 2, 2, 3

PARTITION BY

Rank within groups instead of the entire table:

SQL
-- Top 3 products per category by price
SELECT * FROM (
  SELECT name, category, price,
    ROW_NUMBER() OVER (
      PARTITION BY category
      ORDER BY price DESC
    ) AS rn
  FROM products
) ranked
WHERE rn <= 3;

LAG and LEAD

Access values from previous or next rows - perfect for time-series and period-over-period analysis:

SQL
SELECT order_date,
       revenue,
       LAG(revenue, 1) OVER (ORDER BY order_date) AS prev_day_revenue,
       revenue - LAG(revenue, 1) OVER (ORDER BY order_date) AS daily_change,
       LEAD(revenue, 1) OVER (ORDER BY order_date) AS next_day_revenue
FROM daily_sales;

Running Totals and Moving Averages

SQL
SELECT order_date,
       revenue,
       -- Running total
       SUM(revenue) OVER (
         ORDER BY order_date
         ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
       ) AS running_total,
       -- 7-day moving average
       AVG(revenue) OVER (
         ORDER BY order_date
         ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
       ) AS moving_avg_7d
FROM daily_sales;

NTILE

Divide rows into N equal buckets - useful for creating percentiles and quantiles:

SQL
SELECT name, revenue,
       NTILE(4) OVER (ORDER BY revenue DESC) AS quartile
FROM customers;
Data science tip: Window functions are incredibly powerful for feature engineering. Use LAG to create time-lagged features, running averages for smoothing, and NTILE for binning continuous variables into quantiles.

Ready to Go Deeper?

Live instructor-led courses from our partners. Affiliate disclosure.