Reputation: 680
I have table in my PostgreSQL database like below example. It has an empty column which needed to filled by previous row value
ship_id|ship_class |bow_number|name |date_start_ops|previous_name|
-------|---------------|----------|----------------|--------------|-------------|
010 |Albatross Class| 010|Albatross |1980-01-05 | |
010 |Albatross Class| 909X|AP010 |1979-12-25 | |
012 |Jaguar Class| 010|Jaguar |1978-11-05 | |
012 |Jaguar Class| 8091X|JX010 |1970-05-10 | |
and it must filled like this:
ship_id|ship_class |bow_number|name |date_start_ops|previous_name|
-------|---------------|----------|----------------|--------------|-------------|
010 |Albatross Class| 010|Albatross |1980-01-05 |AP101 |
010 |Albatross Class| 909X|AP010 |1979-12-25 |NULL |
012 |Jaguar Class| 010|Jaguar |1978-11-05 |JX010 |
012 |Jaguar Class| 8091X|JX010 |1970-05-10 |NULL |
I try with this query:
update
historic as a
set
previous_name =
(select
lag(name, 1) over (partition by ship_id, ship_class
order by
date_start_ops)
from
historic
)
where
a.ship_id = ship_id
However it return error: "ERROR: more than one row returned by a subquery used as an expression" Any help are appreciated
Upvotes: 1
Views: 230
Reputation:
Use a derived table that calculates all previous names once and join to that. As your table doesn't have a primary key (which is something you should really change), I used the internal "row identifier" from Postgres: ctid
update historic as a
set previous_name = t.prev_name
from (
select ctid as row_id,
lag(name, 1) over (partition by ship_id, ship_class
order by date_start_ops) as prev_name
from historic
) t
where a.ctid = t.row_id
Upvotes: 3