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

PostgreSQL - LAST_VALUE Function

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.

Syntax:

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.

Usage:

Consider a table sales with the following data:

idsale_dateamount
12023-01-01100
22023-01-02150
32023-01-03200

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.

  1. PostgreSQL LAST_VALUE function example:

    • Use LAST_VALUE in a simple example.
    SELECT LAST_VALUE(column_name) OVER () AS last_value_result FROM example_table;
    
  2. PARTITION BY clause with LAST_VALUE in PostgreSQL:

    • Use 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;
    
  3. ORDER BY clause with LAST_VALUE function in PostgreSQL:

    • Specify the order of rows using the ORDER BY clause.
    SELECT column1, LAST_VALUE(column2) OVER (ORDER BY column3) AS last_value_result
    FROM example_table;
    
  4. 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;
    
  5. LAST_VALUE and NULL values in PostgreSQL:

    • Be aware of how LAST_VALUE behaves with NULL values.
    SELECT LAST_VALUE(column_name IGNORE NULLS) OVER () AS last_value_result FROM example_table;
    
  6. Comparing LAST_VALUE with other window functions in PostgreSQL:

    • Compare 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;
    
  7. Using LAST_VALUE with window frames in PostgreSQL:

    • Apply window frames to define the range of rows considered by 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;
    
  8. LAST_VALUE with IGNORE NULLS in PostgreSQL:

    • Use 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;
    
  9. Using LAST_VALUE in combination with other functions in PostgreSQL:

    • Combine 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;
    
  10. Handling duplicates with LAST_VALUE in PostgreSQL:

    • Be cautious when using LAST_VALUE with duplicate values; results may vary.
    SELECT column1, LAST_VALUE(column2) OVER (ORDER BY column1) AS last_value_result
    FROM example_table;
    
  11. LAST_VALUE and subqueries in PostgreSQL:

    • Use 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;
    
  12. Using LAST_VALUE for running totals in PostgreSQL:

    • Calculate running totals using LAST_VALUE with the SUM function.
    SELECT column1, column2,
           SUM(column2) OVER (ORDER BY column1) AS running_total
    FROM example_table;
    
  13. Using LAST_VALUE with OVER and PARTITION BY in PostgreSQL:

    • Use 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;