FIRST_VALUE() and LAST_VALUE() retrieve the value at the start
and end of a window’s frame. NTILE(n) divides the rows in a
window into n roughly equal-sized buckets and labels each row with
its bucket number.
LAST_VALUE() requires an explicit frame clause to
behave as expected.NTILE().01_ROW_NUMBER04_PARTITION_BYFIRST_VALUE(column) OVER (ORDER BY sort_column) AS first_value
LAST_VALUE(column) OVER (
ORDER BY sort_column
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS last_value
NTILE(n) OVER (ORDER BY sort_column) AS bucket_number
employes joined to departments
| Domain | Scenario |
|---|---|
| Marketing | Split customers into quartiles by spend (NTILE(4)) |
| Banking | First and last transaction per account statement |
| HR | First and last hire in each department |
LAST_VALUE() without the frame clause
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING. By
default, SQL’s window frame is RANGE BETWEEN UNBOUNDED PRECEDING AND
CURRENT ROW, so LAST_VALUE() silently returns the current row
instead of the true last row in the partition – a very common,
hard-to-spot bug.NTILE() produces perfectly equal-sized groups – when the
row count is not evenly divisible by n, the earlier buckets absorb
the extra rows.LAST_VALUE() with an explicit frame clause.NTILE() and why that number
was chosen (quartiles = 4, deciles = 10, etc.).FIRST_VALUE() works correctly with the default frame because
“first” and “current position” align naturally as the window grows;
LAST_VALUE() does not share that property, which is why it is the
single most-cited source of window-function bugs in production code
reviews.
FIRST_VALUE().LAST_VALUE() (with the correct
frame clause).NTILE().Intermediate
25 minutes
LAST_VALUE().NTILE() bucket sizes can differ by one row.← Previous: 05_LAG_LEAD
↑ Module README
→ Next: 07_RUNNING_TOTALS