I have a log table in which a new time stamp is added to the column ts as soon as a change is made, at the same time the time stamp of the last change is written to the column prevts. What I would like to know is the newest update date of a certain field, if a certain field, like in this example the last name, was never updated and is the same since it was created, I would like to know the creation date.
id | ts | prevts | operation | firstname | middlename | lastname |
---|---|---|---|---|---|---|
1 | 2023-02-03T14 | 2023-01-17T08 | update | John | S | Doe |
1 | 2023-01-17T08 | 2022-10-20T03 | update | John | S | Doe |
1 | 2022-10-20T03 | 2022-10-06T14 | update | Johnny | S | Doe |
1 | 2022-10-06T14 | create | Johnny | Doe |
I am able to retrieve the update timestamps for single values like firstname and middle name (like in the code example below) but this does not work for lastname because this condition curr.firstname!=prev.firstname or prev.firstname is null
is not fulfilled. In such cases I would like to know the creation date.
SELECT
DISTINCT ON (curr.id)
curr.id,
prev.ts AS curr_firstname_ts,
curr.prevts
FROM log_table curr
JOIN log_table prev
ON curr.prevts=prev.ts AND prev.id=curr.id
WHERE curr.firstname is not null
AND curr.firstname!=''
AND (curr.firstname!=prev.firstname or prev.firstname is null)
ORDER BY curr.kolid, curr.prevts DESC NULLS LAST, prev.ts;
What I get as a result with this query is:
id | curr_firstname_ts |
---|---|
1 | 2023-01-17T08 |
What I would like to get is something like this:
id | curr_firstname_ts | curr_middlename_ts | curr_lastname_ts |
---|---|---|---|
1 | 2023-01-17T08 | 2022-10-20T03 | 2022-10-06T14 |
select * from log1;
id | currts | prevts | ops | firstname | lastname | middlename |
---|---|---|---|---|---|---|
1 | 2023-02-01 13:00:00 | create | Johnny | Doe | ||
1 | 2023-02-02 13:00:00 | 2023-02-01 13:00:00 | update | Johnny | Doe | S |
1 | 2023-02-03 13:00:00 | 2023-02-02 13:00:00 | update | John | Doe | S |
1 | 2023-02-04 13:00:00 | 2023-02-03 13:00:00 | update | John | Doe | S |
2 | 2023-02-01 13:00:00 | create | Mike | Smith | J |
(5 rows)
Run the query using window functions:
with a as (
select id, currts,prevts, ops,
firstname,lastname,middlename,
max(currts) over (partition by id) as maxts,
min(currts) over (partition by id, firstname) as minfirstnamets ,
min(currts) over (partition by id, lastname) as minlastnamets ,
min(currts) over (partition by id, middlename) as minmiddlenamets
from log1
)
select * from a where currts = maxts;
id | currts | prevts | ops | firstname | lastname | middlename |
---|---|---|---|---|---|---|
1 | 2023-02-01 13:00:00 | create | Johnny | Doe | ||
1 | 2023-02-02 13:00:00 | 2023-02-01 13:00:00 | update | Johnny | Doe | S |
1 | 2023-02-03 13:00:00 | 2023-02-02 13:00:00 | update | John | Doe | S |
1 | 2023-02-04 13:00:00 | 2023-02-03 13:00:00 | update | John | Doe | S |
2 | 2023-02-01 13:00:00 | create | Mike | Smith | J |