SQL Boy
TutorialsPlayground

Format & Validate

SQL FormatterSQL MinifierSyntax Validator

Convert

JSON to SQLCSV to SQLSQL to JSONRegex to SQLExcel to SQLSQL Dialect Convertersoon

Visualize

ER Diagram GeneratorSQL Schema Diff

Generate

SQL Mock Data Generator

Analyze

SQL Query ExplainerSQL Query Analyzer

Workflow hubs

FormattingConversionSchemaAnalysis
View all tools
Daily ChallengeInterviewsCheat SheetBlog

© 2026 SQL Boy. Built for developers.

ContactPrivacyTermsAI Usage PolicyEditorial StandardsAboutRSS Feed

New conversation

What can I help with?

Ask about this page, get a hint on a challenge, or explore SQL concepts.

I know what's on this page and can give answers grounded in SQL Boy content.

Current page

Mastering Sql Lead Lag Functions

/blog/mastering-sql-lead-lag-functions

Usage status will load after login
SQL Boy
TutorialsPlayground

Format & Validate

SQL FormatterSQL MinifierSyntax Validator

Convert

JSON to SQLCSV to SQLSQL to JSONRegex to SQLExcel to SQLSQL Dialect Convertersoon

Visualize

ER Diagram GeneratorSQL Schema Diff

Generate

SQL Mock Data Generator

Analyze

SQL Query ExplainerSQL Query Analyzer

Workflow hubs

FormattingConversionSchemaAnalysis
View all tools
Daily ChallengeInterviewsCheat SheetBlog
Back to Blog
Published 2026-01-17
5 min read

Mastering SQL LEAD and LAG Functions for Row Comparisons

sqlwindow-functionsanalyticsdata-analysisintermediate

Author

SQL Boy Team

Editorial Team at SQL Boy

This article is maintained as part of SQL Boy's hands-on SQL library.

We aim to keep examples runnable, call out dialect differences, and revise unclear sections over time.

Read editorial standardsAbout SQL BoyRequest a correction

If a result or dialect note looks wrong, email [email protected] with the article URL and the section you want reviewed.

Have you ever needed to answer questions like "What was the sales increase from yesterday?" or "Which customer's order amount dropped compared to their last purchase?"

These questions require comparing a row with its neighboring rows. Before window functions, you'd need complex self-joins. Now, SQL provides two elegant functions: LAG() and LEAD().

LEAD and LAG comparing previous and next rows
LEAD and LAG comparing previous and next rows

Understanding LAG and LEAD

Think of your data as a line of people:

  • LAG() looks backward - it grabs data from the person behind you.
  • LEAD() looks forward - it grabs data from the person in front of you.
-- LAG: Get the previous row's value
LAG(column_name) OVER (ORDER BY some_column)

-- LEAD: Get the next row's value
LEAD(column_name) OVER (ORDER BY some_column)

Interactive Example: Daily Sales Comparison

Let's track daily sales and calculate the day-over-day change.

Interactive SQL
Loading...

Notice how the first row has NULL for prev_day_revenue - there's no row before it!

Handling NULL with Default Values

You can provide a default value as the third argument:

-- If there's no previous row, use 0 instead of NULL
LAG(revenue, 1, 0) OVER (ORDER BY sale_date)

The second argument 1 specifies how many rows to look back (default is 1).

Looking Multiple Rows Back

Want to compare with 7 days ago or 2 rows back? Just change the offset:

Interactive SQL
Loading...

Using LEAD to Look Ahead

LEAD works exactly like LAG, but looks at future rows:

Interactive SQL
Loading...

PARTITION BY: Restart for Each Group

When analyzing multiple groups (like different stores), use PARTITION BY to restart the comparison within each group:

Interactive SQL
Loading...

Without PARTITION BY store_name, Store B's first row would incorrectly compare with Store A's last row!

Real-World Use Case: Calculating Growth Rate

Here's a practical example calculating percentage growth:

SELECT 
  month,
  revenue,
  LAG(revenue) OVER (ORDER BY month) as prev_month,
  ROUND(
    (revenue - LAG(revenue) OVER (ORDER BY month)) * 100.0 
    / LAG(revenue) OVER (ORDER BY month), 
    2
  ) as growth_percent
FROM monthly_revenue;

LAG vs LAG: Quick Reference

FunctionDirectionUse Case
LAG(col)Backward ←Compare with previous row
LAG(col, 2)2 rows backWeek-over-week, custom offset
LEAD(col)Forward →Preview next row's value
LEAD(col, 2)2 rows aheadFuture forecasting

Best Practices

  1. Always use ORDER BY: LAG/LEAD need a defined order to know which row is "previous" or "next".

  2. Handle NULLs: The first row for LAG (and last for LEAD) will be NULL. Use COALESCE or the third parameter.

  3. Use PARTITION BY wisely: When comparing within groups, always partition to avoid cross-group comparisons.

  4. Performance: LAG/LEAD are efficient - they don't require self-joins or subqueries.

Tool Workflow

Use tools when neighboring-row logic is correct in theory but still hard to verify

LEAD and LAG simplify row comparisons, but query readability still matters when partitions, offsets, and derived metrics stack up. Use the tools to inspect the final statement before turning it into a report.

SQL Query Explainer

Break down LEAD and LAG clauses so row order, partitioning, and default-value behavior are easier to inspect.

Query Analysis Workflow Hub

Use the broader workflow when row-comparison queries also need validation and analytical review.

Conclusion

LAG and LEAD are essential tools for time-series analysis, trend detection, and row comparison. Instead of complex self-joins:

  • Use LAG() to look at previous rows
  • Use LEAD() to look at next rows
  • Add PARTITION BY for group-level comparisons
  • Set default values to handle edge cases

Master these functions and you'll write cleaner, faster SQL for any analytical reporting task.

Related Articles

  • Understanding Window Functions: A Practical Guide for the foundation that makes LEAD() and LAG() feel less magical.
  • Calculating Running Totals & Moving Averages in SQL for another common window-function workflow built on ordered rows.
  • Year-over-Year Growth SQL Guide for a practical reporting use case where previous-period comparisons matter.
Share this article:

Related Articles

sqlanalytics

SQL for Anomaly Detection: Finding Outliers

Learn how to detect anomalies and statistical outliers in your data using SQL with Z-score, IQR, and moving average methods.

Read more
sqldata-analysis

SQL for Data Analysis: The Ultimate Guide

Move beyond basic SELECTs. Master the core SQL techniques for real-world data analysis: Data Cleaning, Time-Series Analysis, Window Functions, and Cohort Analysis.

Read more
sqldata-analysis

Calculating Percentiles and Median in SQL

AVG tells you the mean, but what about median and percentiles? Learn how to calculate these essential statistics in SQL using window functions and clever tricks.

Read more
Previous

Calculating Running Totals & Moving Averages in SQL

Next

Ranking Data with SQL: RANK, DENSE_RANK, and ROW_NUMBER Explained

Comments

© 2026 SQL Boy. Built for developers.

ContactPrivacyTermsAI Usage PolicyEditorial StandardsAboutRSS Feed