Hi I'm new to postgresql and need a little help.
i have the following table, where rows belong to class 1 or 2 based on the value of column pf. The rows are ordered by charttime.
i want a new column called prev_val, and the prev_val corresponding row should be equal to the last occurring value of the the class diff from the corresponding rows class. ie ex- if pf=2 for a given row then the prev_val of this row must be equal to the previous value of a row with pf=1.
ie
for a given pf=2, prev_val=valuenum of pf=1 with charrttime less than current row
for a given pf=1, prev_val=valuenum of pf=2 with charrttime less than current row
You are looking for the function lag()
. If I understand the question correctly:
select t.*,
lag(valuenum) over (partition by pf order by charttime) as prev_val
from t;
EDIT:
One way to express the logic would be:
select t.*,
(case when pf = 1
then lag(case when pf = 2 then valuenum end ignore nulls) over (partition by pf order by charttime)
then lag(case when pf = 1 then valuenum end ignore nulls) over (partition by pf order by charttime)
end) as prev_other_val
from t;
Unfortunately, Postgres does not yet support ignore nulls
, so this doesn't work. The following might work:
select t.*,
(case when pf = 1
then lag(valuenum) filter (where pf = 2) over (partition by pf order by charttime)
then lag(valuenum) filter (where pf = 1) over (partition by pf order by charttime)
end) as prev_other_val
from t;
This uses the filter
clause for the same (and more efficient) effect.
An alternative that should definitely work (but not on large tables) is a lateral join or subquery:
select t.*,
(select t2.valuenum
from t t2
where t2.pf <> t.pf and t2.chartime < t.chartime
order by t2.chartime desc
fetch first 1 row only
) as prev_other_val
from t;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.