Back to Library

LAG() in SQL

Accesses data from a previous row in the result set within a specified window partition.

Syntax

LAG(expression[, offset[, default_value]]) OVER (
    [PARTITION BY column1, column2, ...]
    ORDER BY column1 [ASC|DESC], column2 [ASC|DESC], ...
)
Return type
Same as input expression type

LAG() Function Example

SELECT product_name, sales_date, sales_amount,
       LAG(sales_amount) OVER (ORDER BY sales_date) AS previous_sales
FROM sales;
-- Output: 'Product A', '2024-12-26', 1000, 800

What is LAG() in SQL?

The LAG() function in SQL allows you to access data from a previous row within the same result set, based on a specified window partition and ordering. It is commonly used for trend analysis, comparing current and previous values, calculating differences, and detecting changes over time.

This function is available in SQL Server, PostgreSQL, Oracle, and MySQL 8.0+ as part of window functions.

This function is widely used in time-series analysis, financial reports, and performance tracking.

Parameters:

  • expression: Column or expression to retrieve from previous row

  • offset (optional): Number of rows back to look (default: 1)

  • default_value (optional): Value to return when no previous row exists

Example Use Cases:

-- Calculate month-over-month growth

SELECT month, revenue,LAG(revenue) OVER (ORDER BY month) AS prev_month_revenue,
revenue - LAG(revenue) OVER (ORDER BY month) AS revenue_change FROM monthly_sales;
-- Output:
month       revenue    prev_month_revenue    revenue_change
-------     -------    -----------------     --------------
2024-01     150000     null                 null
2024-02     165000     150000               15000
2024-03     158000     165000               -7000
2024-04     175000     158000               17000
2024-05     180000     175000               5000

-- Compare with previous year by category

SELECT year, category, sales,LAG(sales, 1, 0) OVER (PARTITION BY category ORDER BY year) AS prev_year_sales FROM yearly_sales;
-- Output:
year    category      sales      prev_year_sales
----    --------      -----      ---------------
2022    Electronics   500000     0
2023    Electronics   550000     500000
2024    Electronics   600000     550000
2022    Clothing      300000     0
2023    Clothing      325000     300000
2024    Clothing      375000     325000

-- Track price changes

SELECT product_id, effective_date, price,LAG(price) OVER (PARTITION BY product_id ORDER BY effective_date) AS previous_price FROM price_history;
-- Output:
product_id    effective_date    price    previous_price
----------    --------------    -----    --------------
P001          2024-01-01       29.99    null
P001          2024-03-15       34.99    29.99
P001          2024-06-01       39.99    34.99
P002          2024-01-01       49.99    null
P002          2024-04-15       54.99    49.99

Notes:

  • Behavior: Returns NULL if no previous row and no default specified

  • Performance Considerations: Window function optimization may be needed

  • Version Info: Core window function available in most modern DBMS

  • Deprecated/Recommended Alternatives: None, standard functionality

Error Handling:

  • Error: Syntax error if ORDER BY is omitted

  • Recommendation: Always include ORDER BY clause and consider default values


Supported Databases:

DBMS
Function / Syntax
Example
Behavior with NULL
MySQL

LAG()

LAG(col) OVER (ORDER BY date)

Returns NULL

PostgreSQL

LAG()

LAG(col) OVER (ORDER BY date)

Returns NULL

SQL Server

LAG()

LAG(col) OVER (ORDER BY date)

Returns NULL

SQLite

LAG()

LAG(col) OVER (ORDER BY date)

Returns NULL

BigQuery

LAG()

LAG(col) OVER (ORDER BY date)

Returns NULL

Snowflake

LAG()

LAG(col) OVER (ORDER BY date)

Returns NULL

Athena

LAG()

LAG(col) OVER (ORDER BY date)

Returns NULL

Related Functions:

CAST/CONVERT()

Converts a value from one data type to another. Both CAST and CONVERT perform the same function with different syntax.

Converts a value from one data type to another. Both CAST and CONVERT perform the same function with different syntax.

Converts a value from one data type to another. Both CAST and CONVERT perform the same function with different syntax.

Converts a value from one data type to another. Both CAST and CONVERT perform the same function with different syntax.

COALESCE()

Returns the first non-null value in a list of expressions, evaluated from left to right.

Returns the first non-null value in a list of expressions, evaluated from left to right.

Returns the first non-null value in a list of expressions, evaluated from left to right.

Returns the first non-null value in a list of expressions, evaluated from left to right.

LAG()

Accesses data from a previous row in the result set within a specified window partition.

Accesses data from a previous row in the result set within a specified window partition.

Accesses data from a previous row in the result set within a specified window partition.

Accesses data from a previous row in the result set within a specified window partition.

DENSE_RANK()

Assigns a rank to rows within a result set partition, with no gaps in rank numbers when ties occur.

Assigns a rank to rows within a result set partition, with no gaps in rank numbers when ties occur.

Assigns a rank to rows within a result set partition, with no gaps in rank numbers when ties occur.

Assigns a rank to rows within a result set partition, with no gaps in rank numbers when ties occur.

CASE

Provides conditional logic in SQL queries, evaluating conditions and returning specified results based on matching conditions.

Provides conditional logic in SQL queries, evaluating conditions and returning specified results based on matching conditions.

Provides conditional logic in SQL queries, evaluating conditions and returning specified results based on matching conditions.

Provides conditional logic in SQL queries, evaluating conditions and returning specified results based on matching conditions.

RANK()

Assigns a rank to rows within a result set partition, with gaps in rank numbers when ties occur.

Assigns a rank to rows within a result set partition, with gaps in rank numbers when ties occur.

Assigns a rank to rows within a result set partition, with gaps in rank numbers when ties occur.

Assigns a rank to rows within a result set partition, with gaps in rank numbers when ties occur.

One place for all your queries,
directly on your SQL editor