Let's say that given a table observations_tbl
with attributes date
(day) and value
, I want to produce the new attribute prev_day_value
to get the following table:
|---------------------|-------|----------------|
| date | value | prev_day_value |
|---------------------|-------|----------------|
| 01.01.2015 00:00:00 | 5 | 0 |
| 02.01.2015 00:00:00 | 4 | 5 |
| 03.01.2015 00:00:00 | 3 | 4 |
| 04.01.2015 00:00:00 | 2 | 3 |
|---------------------|-------|----------------|
I am well-aware that such an output can typically be obtained using a WINDOW
function. But how would I achieve this through a PostgreSQL user defined function? I want to indicate that I am in a situation where I must use a function, difficult to explain why without going into detail - these are the restrictions I have and if anything, it is a technical challenge.
Take into consideration this template query:
SELECT *, lag(value,1) AS prev_day_value -- or lag(record,1) or lag(date,value,1) or lag(date,1) or lag(observations_tbl,1), etc.
FROM observations_tbl
I am using function lag
with parameter 1
to look for a value which comes before the current row by 1
- a distance of 1
row. I don't care what other parameters the function lag
can have (table name, other attributes) - what could the function lag
look like to achieve such functionality? The function can be of any language, SQL
, PL/pgSQL
and even C
using PostgreSQL API/backend.
I understand that one answer can be wrapping a WINDOW
query inside lag
user defined function. But I am thinking that would be a rather costly operation if I have to scan the entire table twice (once inside the lag
function and once outside). I was thinking that maybe each PostgreSQL record would have a pointer to its previous record which is directly accessible? Or that I can somehow open a cursor at this specific row / row number without having to scan the entire table? Or is what I am asking impossible?