Summary: In this tutorial, you’ll learn how to use the PostgreSQL LAG
window function to compare the current row’s value with the previous row.
Getting Started with the PostgreSQL LAG Window Function #
In PostgreSQL, the LAG()
function allows you to access data of a previous row from the current row within the same partition.
You often use the LAG()
function to compare the current row’s value with the previous row, such as sales vs. previous year.
Here’s the syntax of the PostgreSQL LAG
window function:
LAG(value[, offset [, default]]) OVER (
[PARTITION BY partition_expression]
[ORDER BY sort_expression]
)
Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)
In this syntax
value
: A column or expression that you want to return the value of the previous row.offset
: Specifies the number of rows back from the current row you want to retrieve the value. The offset defaults to 1, which accesses the previous row’s value.default
: This is the default value if the previous row does not exist. If you don’t specify a default value, the function returnsNULL
if the current row is the first row in the partition, which has no previous row.PARTITION BY
: Divides the result set into partitions by thepartition_expression
. If you omit thePARTITION BY
clause, theLAG
function treats the whole result set as a single partition.ORDER BY
: Determines the order of the rows within each partition.
PostgreSQL LAG Window Function Examples #
Let’s explore some examples of using the LAG
function with the sales
table and sales_by_years
view:
The sales
table:
SELECT * FROM sales;
Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)
The sales_by_years
view:
SELECT * FROM sales_by_years;
Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)
Using PostgreSQL LAG to Compare Yearly Sales #
The following SELECT
statement uses the LAG()
function to compare the sales amount of each year with the previous year in the sales_by_years
view:
SELECT
year,
amount,
LAG(amount) OVER (
ORDER BY year
) AS previous_year_amount
FROM
sales_by_years;
Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)
Output:
year | amount | previous_year_amount
------+-----------+----------------------
2019 | 513700.00 | NULL
2020 | 490000.00 | 513700.00
2021 | 512000.00 | 490000.00
2022 | 483200.00 | 512000.00
2023 | 491000.00 | 483200.00
Code language: plaintext (plaintext)
How it works:
- The
ORDER BY
clause sorts the rows of the result set by year in ascending order. - The
LAG(amount)
function accesses the amount of the previous year. Note that offset defaults to 1. Since the first row (2019) has no previous row, theLAG()
function returnsNULL
.
Calculating Sales Change Percentage vs. Previous Year #
The following SELECT
statement uses the LAG
window function to calculate the percentage change in sales compared to the previous year:
SELECT
year,
amount,
LAG(amount) OVER (ORDER BY year) AS previous_year_amount,
ROUND((amount - LAG(amount) OVER (ORDER BY year)) / LAG(amount) OVER (ORDER BY year) * 100, 2) AS sales_change_percentage
FROM
sales_by_years;
Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)
Output:
year | amount | previous_year_amount | sales_change_percentage
------+-----------+----------------------+-------------------------
2019 | 513700.00 | NULL | NULL
2020 | 490000.00 | 513700.00 | -4.61
2021 | 512000.00 | 490000.00 | 4.49
2022 | 483200.00 | 512000.00 | -5.63
2023 | 491000.00 | 483200.00 | 1.61
Code language: plaintext (plaintext)
How it works:
LAG(amount) OVER (ORDER BY year)
: Returns the sales amount from the previous year.(amount - LAG(amount) OVER (ORDER BY year)) / LAG(amount) OVER (ORDER BY year) * 100
: Calculates the percentage change in sales compared to the previous year.ROUND()
: Rounds the percentage change to two decimal places.
Comparing Sales by Products #
The following SELECT
statement uses the LAG()
window function to compare the sales of different products year by year:
SELECT
year,
product,
amount,
LAG(amount) OVER (
PARTITION BY product
ORDER BY year
) AS previous_year_amount
FROM
sales;
Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)
Output:
year | product | amount | previous_year_amount
------+---------+-----------+----------------------
2019 | Galaxy | 296000.00 | NULL
2020 | Galaxy | 273000.00 | 296000.00
2021 | Galaxy | 272000.00 | 273000.00
2022 | Galaxy | 258200.00 | 272000.00
2023 | Galaxy | 260000.00 | 258200.00
2019 | iPhone | 217700.00 | NULL
2020 | iPhone | 217000.00 | 217700.00
2021 | iPhone | 240000.00 | 217000.00
2022 | iPhone | 225000.00 | 240000.00
2023 | iPhone | 231000.00 | 225000.00
Code language: plaintext (plaintext)
How it works:
PARTITION BY product
: Divides the rows into partitions based on the product.ORDER BY year
: Orders the rows within each partition by year.LAG(amount)
: Applies to each partition (product) and returns the sales amount from the previous year for the same product.
Comparing Sales vs. Previous Year by Product in Percentage #
The following SELECT
statement uses the LAG()
function to calculate the percentage change in sales for each product compared to the previous year:
SELECT
year,
product,
amount,
LAG(amount) OVER (
PARTITION BY product
ORDER BY year
) AS previous_year_amount,
ROUND(
(
amount - LAG(amount) OVER (
PARTITION BY product
ORDER BY year
)
) / LAG(amount) OVER (
PARTITION BY product
ORDER BY year
) * 100,
2
) AS sales_change_percentage
FROM
sales;
Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)
Output
year | product | amount | previous_year_amount | sales_change_percentage
------+---------+-----------+----------------------+-------------------------
2019 | Galaxy | 296000.00 | NULL | NULL
2020 | Galaxy | 273000.00 | 296000.00 | -7.77
2021 | Galaxy | 272000.00 | 273000.00 | -0.37
2022 | Galaxy | 258200.00 | 272000.00 | -5.07
2023 | Galaxy | 260000.00 | 258200.00 | 0.70
2019 | iPhone | 217700.00 | NULL | NULL
2020 | iPhone | 217000.00 | 217700.00 | -0.32
2021 | iPhone | 240000.00 | 217000.00 | 10.60
2022 | iPhone | 225000.00 | 240000.00 | -6.25
2023 | iPhone | 231000.00 | 225000.00 | 2.67
Code language: plaintext (plaintext)
How it works:
PARTITION BY product
: Divides the result set into partitions based on the product.ORDER BY year
: Sorts the rows within each partition by year in ascending order.LAG(amount)
: Retrieves the sales amount from the previous year for the same product.(amount - LAG(amount) OVER (PARTITION BY product ORDER BY year)) / LAG(amount) OVER (PARTITION BY product ORDER BY year) * 100
: Calculates the percentage change in sales for the same product compared to the previous year.ROUND
: Rounds the percentage change to two decimal places.
Summary #
- Use the PostgreSQL
LAG()
window function to access data from a previous row in the same partition.