Chaturmind
LearnDSASystem DesignBlogPremium
Sign inGet started
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML

Company

  • Blog
  • Premium
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Database Fundamentals

Database Foundations

  • ACID Properties
  • Indexes & Query Performance
  • Transactions & Isolation Levels

Database Design

  • Normalization (1NF–3NF)
  • SQL Joins & Set Operations
  • Window Functions
Chaturmind
← Database Fundamentals

Database Foundations

  • ACID Properties
  • Indexes & Query Performance
  • Transactions & Isolation Levels

Database Design

  • Normalization (1NF–3NF)
  • SQL Joins & Set Operations
  • Window Functions
HomeLearnDatabasesDatabase FundamentalsAdvanced Querying
✓ FreeAdvanced· 13 min read

Window Functions

Use ROW_NUMBER, RANK, LAG, LEAD, and aggregates over windows for powerful analytical queries.

Published April 6, 2025


Window Functions

Window functions perform calculations across a set of rows related to the current row — without collapsing rows like GROUP BY does. They are one of the most powerful SQL features and a frequent advanced interview topic.

Syntax

function_name() OVER (
    PARTITION BY column   -- optional: group rows
    ORDER BY column       -- optional: define row order within window
    ROWS/RANGE BETWEEN ... -- optional: frame specification
)

ROW_NUMBER, RANK, DENSE_RANK

SELECT
    name,
    dept,
    salary,
    ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) AS row_num,
    RANK()       OVER (PARTITION BY dept ORDER BY salary DESC) AS rank,
    DENSE_RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS dense_rank
FROM employees;

-- If two people tie for rank 1:
-- ROW_NUMBER:  1, 2, 3 (no ties)
-- RANK:        1, 1, 3 (skips 2)
-- DENSE_RANK:  1, 1, 2 (no gaps)

LAG and LEAD — access adjacent rows

SELECT
    order_date,
    revenue,
    LAG(revenue, 1)  OVER (ORDER BY order_date) AS prev_day_revenue,
    LEAD(revenue, 1) OVER (ORDER BY order_date) AS next_day_revenue,
    revenue - LAG(revenue, 1) OVER (ORDER BY order_date) AS day_over_day_change
FROM daily_revenue;

Running Totals with SUM OVER

SELECT
    order_date,
    revenue,
    SUM(revenue) OVER (ORDER BY order_date
                       ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
                      ) AS running_total
FROM daily_revenue;

Moving Average

SELECT
    order_date,
    revenue,
    AVG(revenue) OVER (
        ORDER BY order_date
        ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
    ) AS seven_day_avg
FROM daily_revenue;

NTILE — divide rows into buckets

SELECT name, salary,
    NTILE(4) OVER (ORDER BY salary DESC) AS quartile
FROM employees;
-- quartile 1 = top 25% earners

Classic Interview Query — Top N per Group

-- Top 2 earners per department
SELECT dept, name, salary FROM (
    SELECT dept, name, salary,
           ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) AS rn
    FROM employees
) ranked
WHERE rn <= 2;

Interview Tips

  1. The top N per group query appears in nearly every advanced SQL interview.
  2. Know the difference between RANK (gaps) and DENSE_RANK (no gaps) — interviewers love asking this.
  3. LAG/LEAD are perfect for time-series comparisons — have a working example ready.
  4. PARTITION BY is optional — omitting it applies the window function across all rows.

Previous

SQL Joins & Set Operations

AI Tutor

Lesson: Window Functions

Quick actions

AI responses can be inaccurate. Verify critical information.