Mastering LAG and LEAD in SQL Server

Morteza JangjooMorteza Jangjoo
3 min read

When analyzing data in SQL Server, you often need to look at values from previous or next rows — for example, to calculate trends, compare sales over time, or detect changes in a sequence.

Two powerful window functions, LAG() and LEAD(), make this incredibly easy.


What Are LAG and LEAD?

  • LAG(): Returns data from a previous row relative to the current row in a result set.

  • LEAD(): Returns data from a next row relative to the current row.

Both functions work with OVER() clauses and windowing to define how rows are ordered and compared.


Basic Syntax

LAG(column_name, offset, default_value) OVER (ORDER BY some_column)
LEAD(column_name, offset, default_value) OVER (ORDER BY some_column)
  • column_name: The column whose value you want from the previous/next row.

  • offset: How many rows behind/ahead to look (default is 1).

  • default_value: Value returned if there is no previous/next row (optional).


Example Dataset

Let’s create a simple sales table:

CREATE TABLE Sales (
    Id INT,
    SaleDate DATE,
    Amount DECIMAL(10,2)
);

INSERT INTO Sales VALUES
(1, '2025-08-01', 100.00),
(2, '2025-08-02', 120.00),
(3, '2025-08-03', 90.00),
(4, '2025-08-04', 150.00);

Using LAG

SELECT 
    SaleDate,
    Amount,
    LAG(Amount, 1, 0) OVER (ORDER BY SaleDate) AS PreviousAmount
FROM Sales;

Result:

SaleDateAmountPreviousAmount
2025-08-01100.000.00
2025-08-02120.00100.00
2025-08-0390.00120.00
2025-08-04150.0090.00

Here, LAG() lets us compare the current day’s sales with the previous day’s.


Using LEAD

SELECT 
    SaleDate,
    Amount,
    LEAD(Amount, 1, 0) OVER (ORDER BY SaleDate) AS NextAmount
FROM Sales;

Result:

SaleDateAmountNextAmount
2025-08-01100.00120.00
2025-08-02120.0090.00
2025-08-0390.00150.00
2025-08-04150.000.00

Here, LEAD() gives us the next day’s sales for each record.


Practical Use Case: Sales Difference

We can combine LAG() to calculate day-over-day changes:

SELECT 
    SaleDate,
    Amount,
    Amount - LAG(Amount, 1, Amount) OVER (ORDER BY SaleDate) AS ChangeFromPreviousDay
FROM Sales;

Result:

SaleDateAmountChangeFromPreviousDay
2025-08-01100.000.00
2025-08-02120.0020.00
2025-08-0390.00-30.00
2025-08-04150.0060.00

Key Points

  • LAG() is perfect for comparing with previous rows.

  • LEAD() is ideal for comparing with next rows.

  • Always use ORDER BY in your OVER() clause to define the row sequence.

  • You can provide a default value to handle missing previous/next rows.


Conclusion
LAG() and LEAD() are powerful tools for analyzing trends, detecting changes, and comparing sequential data without writing complex self-joins. They make your SQL cleaner, faster, and easier to maintain.


I’m Morteza Jangjoo and “Explaining things I wish someone had explained to me”

0
Subscribe to my newsletter

Read articles from Morteza Jangjoo directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Morteza Jangjoo
Morteza Jangjoo