I have a table t
that has the following data:
name | n
------------+---
school | 4
hotel | 2
restaurant | 6
school | 3
school | 5
hotel | 1
When I run the following query, the result is somewhat odd.
select name, n,
first_value(n) over (partition by name order by n desc),
last_value(n) over (partition by name order by n)
from t;
name | n | first_value | last_value
------------+---+-------------+------------
hotel | 1 | 2 | 1
hotel | 2 | 2 | 2
restaurant | 6 | 6 | 6
school | 3 | 5 | 3
school | 4 | 5 | 4
school | 5 | 5 | 5
(6 rows)
Although first_value
works as I expected, last_value
works strange. I think the values of last_value
column should be the same as first_value
's because the first_value
is order by n
descending.
Is this a PostgreSQL's bug or am I missed something?
The version of PostgreSQL is:
postgres=# select version();
version
-----------------------------------------------------------------------------------------------------------------------------------
PostgreSQL 9.4.1 on x86_64-apple-darwin14.1.0, compiled by Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn), 64-bit
(1 row)
No, this is not a bug. The first_value()
and last_value()
functions work on the window frame, not the partition. The window frame, as per the documentation, defaults to the start of the partition to the current row if no frame_clause
is specified. That is just what you need for first_value()
but for last_value()
you should add range between unbounded preceding and unbounded following
to your WINDOW
definition to look beyond the current row:
select name, n,
first_value(n) over (partition by name order by n desc),
last_value(n) over (partition by name order by n
range between unbounded preceding and unbounded following)
from t;
Note also that this has nothing to do with ordering of the rows in the partition. The ordering produces the partition in a certain order (not surprisingly) and the frame-based functions then work on the window frame without knowing or caring about any ordering of the rows.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With