LAST_VALUE()

SQL · Window Functions

Theory

LAST_VALUE(column) returns the value from the last row of the window frame. This sounds like the opposite of FIRST_VALUE, but there is a trap. When the window has an ORDER BY and no frame, the default frame ends at the current row (and its peers). So the 'last row of the frame' is usually the current row itself, and LAST_VALUE just echoes each row's own value.

To get the true last row of the partition, write the frame explicitly: ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING. With PARTITION BY dept ORDER BY salary DESC and that frame, LAST_VALUE(name) gives the lowest earner in each department on every row. An often simpler alternative is FIRST_VALUE with the sort order reversed (ORDER BY salary ASC), which needs no frame. Related: NTH_VALUE(column, n) returns the n-th row of the frame and has the same frame rule.

Why we use it

Sometimes you need the value from the end of an ordered group: the latest status, the closing price, the lowest earner. LAST_VALUE does this without a subquery, as long as you set the frame to cover the whole partition.

When to use it

Use LAST_VALUE with an explicit UNBOUNDED FOLLOWING frame when you need the last row's value. Prefer FIRST_VALUE with the opposite ORDER BY when you want something easier to read and harder to get wrong.

How it works

  1. Rows split by PARTITION BY and sorted by ORDER BY
  2. Frame has UNBOUNDED FOLLOWING? Yes: Frame = whole partition. No: Frame stops at current row.
  3. Read the column from the last row of the frame
  4. Used the default frame? Yes: Usually the row's own value (bug). No: True last value.
  5. Value shown on each row

Syntax

LAST_VALUE(column) OVER (
  ORDER BY col
  ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
)

Example

SELECT name, department, salary,
  LAST_VALUE(name) OVER (PARTITION BY department ORDER BY salary DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS lowest_earner
FROM employees;

Key points

SQL topics

Introduction to SQL

Querying Data

Sorting Rows

Limiting Rows

Filtering Rows

Joining Multiple Tables

Grouping Rows

SET Operators

Working with Tables

Modifying Data

Views & Triggers

Conditional Expressions

SQL Subqueries

Aggregate Functions

Window Functions

String Functions

Date Functions

Math Functions

Extra Concepts

T
Tech Town
Log InSign Up Free
Home SQL Python DSA Power BI Snowflake Databricks Spark Gen AI Practice Problems Contest Blog

Master SQL from Zero to Pro

All SQL topics in one place. Click any topic in the sidebar — content opens right here without leaving the page.

{{ sectionCount }}
Sections
{{ topicCount }}
Topics
Free
Forever
Hands-on practice Practice SQL Online Solve 150 SQL interview problems in a live editor with instant checking. Start practising →
Section {{ sec.num }}

{{ sec.label }}

SQL  /  {{ current.sectionLabel }}  /  {{ current.name }}

{{ current.name }}

Theory

{{ current.def }}

Why we use it

{{ rich.why }}

When to use it

{{ rich.when }}

Diagram

{{ rich.dg.caption }}

{{ tb.title }}
{{ c.v }}
{{ rich.dg.op }}
➜
{{ rich.dg.output.title }}
{{ c.v }}
{{ nd.label }}
{{ nd.sub }}
{{ nd.label }}
{{ nd.sub }}
{{ rich.dg.left.title }}
{{ it }}
{{ rich.dg.right.title }}
{{ it }}
Flowchart — how it works
{{ nd.text }}
{{ nd.text }}
◇ {{ nd.text }}
Yes → {{ nd.yes }}
No → {{ nd.no }}
Syntax
{{ current.syntax }}
Example
{{ current.example }}
▶ Try It Live — runs against a real sample database
{{ liveError }}
{{ col }}
{{ cell }}
Key Points — click to check off as you learn
  • {{ pt.mark }} {{ pt.text }}

Share this topic