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_VALUEfunction retrieves the value.OVER: Defines the window over which theNTH_VALUEfunction applies.PARTITION BY: Divides the result set into partitions by thepartition_expression. Thepartition_expressioncan 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.00Code language: PostgreSQL SQL dialect and PL/pgSQL (pgsql)How it works:
- The
ORDER BYclause sorts the rows in thesales_by_yearsview 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.42How it works:
- The
NTH_VALUEfunction 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) * 100calculates 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.00How 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.11How 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) * 100computes 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_VALUEwindow function to access a specific value within the same partition.