Summary: in this tutorial, you’ll learn how to use the PostgreSQL NTH_VALUE()
window function to access the nth row in a window frame.
Getting Started with the PostgreSQL NTH_VALUE Window Function #
The NTH_VALUE()
is a window function that allows you to access the nth row within a window frame.
Here’s the syntax of the NTH_VALUE()
window function:
NTH_VALUE(value, n) OVER (
[PARTITION BY partition_expression]
[ORDER BY sort_expression]
[frame_clause]
)
Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)
In this syntax:
value
: This is a column or expression to retrieve the value from the nth row.n
: Specifies the row number within the window frame from which theNTH_VALUE
function retrieves the value.OVER
: Defines the window over which theNTH_VALUE
function applies.PARTITION BY
: Divides the result set into partitions by thepartition_expression
. Thepartition_expression
can be one or more columns to group rows into partitions. If you omit thePARTITION BY
, the function treats the entire result set as a single partition.ORDER BY
: Sorts the rows within each partition.frame_clause
: Defines the window frame for the function.
The NTH_VALUE()
function returns the value from the nth row of a window frame. If the nth row does not exist, the NTH_VALUE()
function returns NULL
.
The NTH_VALUE
function is helpful for comparing a specific row with other rows within the same window frame.
PostgreSQL NTH_VALUE Window Function Examples #
Let’s explore some examples of using the NTH_VALUE
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 NTH_VALUE Window Function to Compare Yearly Sales #
The following SELECT
statement uses the NTH_VALUE
function to compare the sales amount of each year with the sales amount of the first year:
SELECT
year,
amount,
NTH_VALUE(amount, 1) OVER (ORDER BY year) AS first_year_amount
FROM
sales_by_years;
Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)
Output:
year | amount | first_year_amount
------+-----------+-------------------
2019 | 513700.00 | 513700.00
2020 | 490000.00 | 513700.00
2021 | 512000.00 | 513700.00
2022 | 483200.00 | 513700.00
2023 | 491000.00 | 513700.00
Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)
How it works:
- The
ORDER BY
clause sorts the rows in thesales_by_years
view by the year in ascending order. - The
NTH_VALUE(amount, 1)
retrieves the amount value of the first row.
The query returns the sales amount for each year alongside the sales amount from the first year, making it easy to compare.
Calculating Sales Change Percentage vs. First Year #
The following SELECT
statement uses the NTH_VALUE
function to calculate the percentage change in sales compared to the first year:
SELECT
year,
amount,
NTH_VALUE(amount, 1) OVER (ORDER BY year) AS first_year_amount,
ROUND(
(
amount - NTH_VALUE(amount, 1) OVER (ORDER BY year)
) / NTH_VALUE(amount, 1) 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 | first_year_amount | sales_change_percentage
------+-----------+-------------------+-------------------------
2019 | 513700.00 | 513700.00 | 0.00
2020 | 490000.00 | 513700.00 | -4.61
2021 | 512000.00 | 513700.00 | -0.33
2022 | 483200.00 | 513700.00 | -5.94
2023 | 491000.00 | 513700.00 | -4.42
How it works:
- The
NTH_VALUE
function returns the amount of the first row (year). - The expression
(amount - NTH_VALUE(amount, 1) OVER (ORDER BY year)) / NTH_VALUE(amount, 1) OVER (ORDER BY year) * 100
calculates the percentage change in sales compared to the first year. - The
ROUND()
function rounds the percentage change to two decimal places.
Comparing Sales by Products #
The following SELECT
statement uses the NTH_VALUE()
window function to compare the sales of different products year by year with the first year’s sales for each product:
SELECT
year,
product,
amount,
NTH_VALUE(amount, 1) OVER (PARTITION BY product ORDER BY year) AS first_year_amount
FROM sales;
Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)
Output:
year | product | amount | first_year_amount
------+---------+-----------+-------------------
2019 | Galaxy | 296000.00 | 296000.00
2020 | Galaxy | 273000.00 | 296000.00
2021 | Galaxy | 272000.00 | 296000.00
2022 | Galaxy | 258200.00 | 296000.00
2023 | Galaxy | 260000.00 | 296000.00
2019 | iPhone | 217700.00 | 217700.00
2020 | iPhone | 217000.00 | 217700.00
2021 | iPhone | 240000.00 | 217700.00
2022 | iPhone | 225000.00 | 217700.00
2023 | iPhone | 231000.00 | 217700.00
How it works:
PARTITION BY
: Divides the result set into partitions based on the product.ORDER BY year
: Sorts the rows within each partition by year.NTH_VALUE(amount, 1) OVER (PARTITION BY product ORDER BY year)
: Returns the amount from the first year for the same partition (or product).
Comparing Sales vs. First Year by Product in Percentage #
The following SELECT
statement uses the NTH_VALUE()
window function to calculate the percentage change in sales for each product compared to the first year:
SELECT
year,
product,
amount,
NTH_VALUE(amount, 1) OVER (PARTITION BY product ORDER BY year) AS first_year_amount,
ROUND((amount - NTH_VALUE(amount, 1) OVER (PARTITION BY product ORDER BY year)) / NTH_VALUE(amount, 1) 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 | first_year_amount | sales_change_percentage
------+---------+-----------+-------------------+-------------------------
2019 | Galaxy | 296000.00 | 296000.00 | 0.00
2020 | Galaxy | 273000.00 | 296000.00 | -7.77
2021 | Galaxy | 272000.00 | 296000.00 | -8.11
2022 | Galaxy | 258200.00 | 296000.00 | -12.77
2023 | Galaxy | 260000.00 | 296000.00 | -12.16
2019 | iPhone | 217700.00 | 217700.00 | 0.00
2020 | iPhone | 217000.00 | 217700.00 | -0.32
2021 | iPhone | 240000.00 | 217700.00 | 10.24
2022 | iPhone | 225000.00 | 217700.00 | 3.35
2023 | iPhone | 231000.00 | 217700.00 | 6.11
How it works:
PARTITION BY
: Divides the result set into partitions based on the product.ORDER BY
: Sorts the rows within each partition by year in ascending order.NTH_VALUE
: Returns the amount from the first year for the same product.- The expression
(amount - NTH_VALUE(amount, 1) OVER (PARTITION BY product ORDER BY year)) / NTH_VALUE(amount, 1) OVER (PARTITION BY product ORDER BY year) * 100
computes the percentage change in sales compared to the first year for the same product. ROUND
: Rounds the percentage change to two decimal places.
Summary #
- Use the
NTH_VALUE
window function to access a specific value within the same partition.