PostgreSQL Tutorial
Data Types
Querying & Filtering Data
Managing Tables
Modifying Data
Conditionals
Control Flow
Transactions & Constraints
Working with JOINS & Schemas
Roles & Permissions
Working with Sets
Subquery & CTEs
User-defined Functions
Important In-Built Functions
PostgreSQL PL/pgSQL
Variables & Constants
Stored Procedures
Working with Triggers
Working with Views & Indexes
Errors & Exception Handling
The LAST_VALUE
function in PostgreSQL is a window function that returns the last value in an ordered set of values. If you're familiar with spreadsheet software, it's a bit like having a moving window (or range) of cells and always picking the last value from this range.
LAST_VALUE ( expression ) OVER ( PARTITION BY partition_expression ORDER BY sort_expression [ROWS BETWEEN ... AND ...] )
expression
: The column or expression that you want to retrieve the last value for.
PARTITION BY
: This divides the result set into partitions and the LAST_VALUE
function is applied to each partition. It's optional.
ORDER BY
: This sorts the data in a specific order. For LAST_VALUE
to make sense, you typically need an ORDER BY
clause.
ROWS BETWEEN ... AND ...
: It's used to specify the range of rows associated with the current row. If you omit it, the function treats the window as the entire partition.
Consider a table sales
with the following data:
id | sale_date | amount |
---|---|---|
1 | 2023-01-01 | 100 |
2 | 2023-01-02 | 150 |
3 | 2023-01-03 | 200 |
To find out the last sale amount for each date:
SELECT sale_date, amount, LAST_VALUE(amount) OVER (ORDER BY sale_date) as last_value FROM sales;
However, there's a common pitfall when using LAST_VALUE
without a specific frame definition (like ROWS BETWEEN
). Without specifying, the default frame is RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
, which means that for each row, it will consider all rows from the start of the partition up to the current row. Thus, it may not always return the actual last value in the full dataset.
To ensure you always get the very last value, you can define the frame explicitly:
SELECT sale_date, amount, LAST_VALUE(amount) OVER (ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as last_value FROM sales;
This ensures the window frame always covers the entire partition, and you'll get the expected last value for each row.
In practice, when using LAST_VALUE
, always be careful with the window frame definition to ensure you're getting the results you expect.
PostgreSQL LAST_VALUE function example:
LAST_VALUE
in a simple example.SELECT LAST_VALUE(column_name) OVER () AS last_value_result FROM example_table;
PARTITION BY clause with LAST_VALUE in PostgreSQL:
PARTITION BY
to divide the result set into partitions, and ORDER BY
to define the order within each partition.SELECT column1, LAST_VALUE(column2) OVER (PARTITION BY column1 ORDER BY column3) AS last_value_result FROM example_table;
ORDER BY clause with LAST_VALUE function in PostgreSQL:
ORDER BY
clause.SELECT column1, LAST_VALUE(column2) OVER (ORDER BY column3) AS last_value_result FROM example_table;
Using LAST_VALUE with different data types in PostgreSQL:
LAST_VALUE
can be used with different data types.SELECT LAST_VALUE(numeric_column) OVER () AS last_numeric_value FROM example_table;
LAST_VALUE and NULL values in PostgreSQL:
LAST_VALUE
behaves with NULL values.SELECT LAST_VALUE(column_name IGNORE NULLS) OVER () AS last_value_result FROM example_table;
Comparing LAST_VALUE with other window functions in PostgreSQL:
LAST_VALUE
with other window functions like FIRST_VALUE
or SUM
.SELECT column1, LAST_VALUE(column2) OVER () AS last_value_result, FIRST_VALUE(column3) OVER () AS first_value_result, SUM(column4) OVER () AS sum_result FROM example_table;
Using LAST_VALUE with window frames in PostgreSQL:
LAST_VALUE
.SELECT column1, column2, LAST_VALUE(column2) OVER (ORDER BY column1 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS last_value_result FROM example_table;
LAST_VALUE with IGNORE NULLS in PostgreSQL:
IGNORE NULLS
to exclude NULL values from the calculation.SELECT column1, LAST_VALUE(column2 IGNORE NULLS) OVER (ORDER BY column1) AS last_value_result FROM example_table;
Using LAST_VALUE in combination with other functions in PostgreSQL:
LAST_VALUE
with other functions for more complex calculations.SELECT column1, LAST_VALUE(column2 + column3) OVER (ORDER BY column1) AS last_value_result FROM example_table;
Handling duplicates with LAST_VALUE in PostgreSQL:
LAST_VALUE
with duplicate values; results may vary.SELECT column1, LAST_VALUE(column2) OVER (ORDER BY column1) AS last_value_result FROM example_table;
LAST_VALUE and subqueries in PostgreSQL:
LAST_VALUE
in subqueries for more advanced queries.SELECT column1, (SELECT LAST_VALUE(column2) OVER (ORDER BY column1) FROM example_table) AS last_value_result FROM example_table;
Using LAST_VALUE for running totals in PostgreSQL:
LAST_VALUE
with the SUM
function.SELECT column1, column2, SUM(column2) OVER (ORDER BY column1) AS running_total FROM example_table;
Using LAST_VALUE with OVER and PARTITION BY in PostgreSQL:
LAST_VALUE
with both OVER
and PARTITION BY
for a more refined analysis.SELECT column1, column2, LAST_VALUE(column2) OVER (PARTITION BY column1 ORDER BY column3) AS last_value_result FROM example_table;