0

Imagine a sample table

CREATE TABLE mytable (myid integer, myval double precision);

I want to update myval to the previous value, ordered by myid, if a condition is met (that myval is equal to 0).

For that to work properly, the query has to start updating from the lowest myid and end with the highest one.

I really don't know from where to start this time. The following says that window functions are not allowed in UPDATE:

UPDATE mytable
SET myval = LAG(myval) OVER (ORDER BY myid)
WHERE myval = 0
RETURNING *;

And more complex alternatives with FROM subqueries have ended in syntax errors or dumb outputs because the subquery is evaluated once instead of once per row. This last phrase makes me think about the SELECT ... LEFT JOIN LATERAL ... structure, but I haven't been able to make it work with the update statement.

asked Nov 2, 2021 at 10:23
1
  • You can always use the cursor in such situations. Commented Nov 2, 2021 at 11:43

1 Answer 1

1

You can use the window function inside a CTE, for example:

WITH new_values AS (
 FROM myid, lagged
 FROM (
 SELECT *, LAG(myval) OVER (ORDER BY myid) lagged
 FROM mytable
 ) foo 
 WHERE myval = 0
) 
UPDATE mytable l
SET myval = lagged
FROM new_values n
WHERE l.myid = n.myid
RETURNING *;
answered Mar 18, 2022 at 15:46

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.