Reputation: 1318
I'm trying to call Lag($1, 1)
within a function to refer to an older value however I just get a null value instead. Is it invalid to call Lag()
on $1
and, if so, is there an alternative?
Query if anyone wants to try:
CREATE OR REPLACE FUNCTION lag_test(decimal, rn decimal)
RETURNS decimal LANGUAGE SQL AS $$
SELECT CASE WHEN rn % 5 = 0 THEN LAG($1, 1) OVER ()
ELSE $1 * 2
END;
$$;
DO $$ BEGIN
CREATE AGGREGATE lagt ( decimal ) (
INITCOND = 1,
SFUNC = lag_test,
STYPE = decimal
);
EXCEPTION
WHEN duplicate_function THEN NULL;
END $$;
WITH dat AS (
SELECT row_number() OVER () as rn, num
FROM generate_series(2, 20, 2) num
)
SELECT a.*,
lagt(a.rn) OVER (ORDER BY a.rn)
FROM dat a
+-----+-----+------+
| rn | num | lagt |
+-----+-----+------+
| 1 | 2 | 2 |
| 2 | 4 | 4 |
| 3 | 6 | 8 |
| 4 | 8 | 16 |
| 5 | 10 | |
| ... | ... | ... |
+-----+-----+------+
I expected to get 8 however I got a null value instead
Upvotes: 1
Views: 283
Reputation: 46239
PostgreSQL
LAG()
function provides access to a row that comes before the current row at a specified physical offset. In other words, from the current row, the LAG() function can access data of the previous row, or the row before the previous row, and so on.
I think you can't do that because of LAG
function access data of the previous row but in function, lag_test
didn't know what's the data of the previous row (by parameter)
So you will get NULL
.
I think you this query will work for you.
WITH dat AS (
SELECT row_number() OVER () as rn, num
FROM generate_series(2, 20, 2) num
)
SELECT a.*,
CASE WHEN rn % 5 = 0 THEN LAG(num) OVER(ORDER BY a.rn)
ELSE num * 2 END
FROM dat a
Upvotes: 2