Thursday, June 18, 2026

LEAD() and LAG() are window functions

 

LEAD() and LAG() are window functions used to access values from the next row or previous row without using a self-join.

Sample Employees Table

EmployeeIDEmployeeNameSalary
1Alice3000
2Bob4000
3Charlie2500
4David5000
5Emma3500

1. LAG() Example

Get the previous employee's salary:

SELECT
    EmployeeID,
    EmployeeName,
    Salary,
    LAG(Salary) OVER (
        ORDER BY EmployeeID
    ) AS PreviousSalary
FROM Employees;

Output

EmployeeIDEmployeeNameSalaryPreviousSalary
1Alice3000NULL
2Bob40003000
3Charlie25004000
4David50002500
5Emma35005000

LAG() looks backward.


2. LEAD() Example

Get the next employee's salary:

SELECT
    EmployeeID,
    EmployeeName,
    Salary,
    LEAD(Salary) OVER (
        ORDER BY EmployeeID
    ) AS NextSalary
FROM Employees;

Output

EmployeeIDEmployeeNameSalaryNextSalary
1Alice30004000
2Bob40002500
3Charlie25005000
4David50003500
5Emma3500NULL

LEAD() looks forward.


3. Compare Salary with Previous Employee

SELECT
    EmployeeID,
    EmployeeName,
    Salary,
    LAG(Salary) OVER (ORDER BY EmployeeID) AS PrevSalary,
    Salary - LAG(Salary) OVER (ORDER BY EmployeeID) AS Difference
FROM Employees;

Output

EmployeeSalaryPrevSalaryDifference
Alice3000NULLNULL
Bob400030001000
Charlie25004000-1500
David500025002500
Emma35005000-1500

Useful for salary growth/decline analysis.


4. Using Offset

Previous 2nd Employee Salary

SELECT
    EmployeeID,
    EmployeeName,
    Salary,
    LAG(Salary, 2) OVER (
        ORDER BY EmployeeID
    ) AS Salary2RowsBack
FROM Employees;

Output:

EmployeeSalarySalary2RowsBack
Alice3000NULL
Bob4000NULL
Charlie25003000
David50004000
Emma35002500

5. Default Value Example

Instead of NULL:

SELECT
    EmployeeID,
    EmployeeName,
    Salary,
    LAG(Salary, 1, 0) OVER (
        ORDER BY EmployeeID
    ) AS PreviousSalary
FROM Employees;

Output:

EmployeeSalaryPreviousSalary
Alice30000
Bob40003000
Charlie25004000
David50002500
Emma35005000

Syntax

LAG

LAG(column_name, offset, default_value)
OVER (ORDER BY column_name)

LEAD

LEAD(column_name, offset, default_value)
OVER (ORDER BY column_name)

Interview Use Cases

  • Compare current row with previous row.

  • Find salary increase/decrease.

  • Calculate month-over-month sales growth.

  • Detect gaps in dates or sequences.

  • Compare employee performance with previous/next employee.

  • Find consecutive records (attendance, login history, transactions).

SUM() OVER() is a window function often used to calculate a running total without grouping rows.

 

SUM() OVER() is a window function often used to calculate a running total without grouping rows.

Sample Employees Table

EmployeeIDEmployeeNameSalary
1Alice3000
2Bob4000
3Charlie2500
4David5000
5Emma3500

Running Total of Salaries

SELECT
    EmployeeID,
    EmployeeName,
    Salary,
    SUM(Salary) OVER (
        ORDER BY EmployeeID
    ) AS RunningTotal
FROM Employees;

Output

EmployeeIDEmployeeNameSalaryRunningTotal
1Alice30003000
2Bob40007000
3Charlie25009500
4David500014500
5Emma350018000

How it works

For each row:

  • Alice → 3000

  • Alice + Bob → 7000

  • Alice + Bob + Charlie → 9500

  • Alice + Bob + Charlie + David → 14500

  • Alice + Bob + Charlie + David + Emma → 18000

The window function is effectively doing:

SUM(Salary) OVER (
    ORDER BY EmployeeID
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
)

which means:

  • Start from the first row (UNBOUNDED PRECEDING)

  • Keep adding values up to the current row (CURRENT ROW)

Running Total by Department

Suppose the table has a department column:

EmployeeIDEmployeeNameDepartmentSalary
1AliceHR3000
2BobHR4000
3CharlieIT2500
4DavidIT5000
5EmmaHR3500
SELECT
    EmployeeID,
    EmployeeName,
    Department,
    Salary,
    SUM(Salary) OVER (
        PARTITION BY Department
        ORDER BY EmployeeID
    ) AS DeptRunningTotal
FROM Employees;

Output

EmployeeIDEmployeeNameDepartmentSalaryDeptRunningTotal
1AliceHR30003000
2BobHR40007000
5EmmaHR350010500
3CharlieIT25002500
4DavidIT50007500

Here, PARTITION BY Department restarts the running total for each department.

Formula:

SUM(column_name) OVER (
    [PARTITION BY partition_column]
    ORDER BY order_column
)

This is one of the most common SQL interview questions involving window functions.