Reputation: 402
I want to select last row (by mod_date
) where column new_status
is different from previous entry for given object_id
.
At first I tried with row_number but not made it, later I came up with lead/lag functions and I think I'm closer to solution but still not ideal results.
Here's the code and the fiddle: https://www.db-fiddle.com/f/kS8SAi2WsAjfFLomd7t2it/0
CREATE TABLE changes
(object_id integer,
new_status smallint,
comment text,
mod_date timestamp);
INSERT INTO changes
VALUES
(1001, 0, null, '2020-06-01 12:01'),
(1001, 1, 'XYZ', '2020-06-01 12:05'),
(1001, 1, 'YZX', '2020-06-01 12:11'),
(1002, 1, 'XYZ', '2020-06-01 13:21'),
(1002, 1, 'AAA', '2020-06-01 13:25'),
(1002, 0, 'BCA', '2020-06-01 14:11'),
(1003, 1, 'AXX', '2020-06-01 14:12'),
(1003, 0, 'YZX', '2020-06-01 14:13'),
(1003, 0, 'YYY', '2020-06-01 14:17');
SELECT object_id, min(mod_date), new_status FROM (
SELECT
object_id
, mod_date
, new_status
--, row_number() over (partition BY object_id ORDER BY mod_date desc) rn
, lag(new_status) OVER (partition by object_id ORDER BY mod_date desc) as next_status
FROM changes
ORDER BY 1)x
WHERE new_status = next_status
OR next_status is null
GROUP BY 1,3
The output for 1001, and 1003 is fine, for 1002 it should be row with status 0.
Appreciate any help and suggestions!
Upvotes: 1
Views: 59
Reputation: 1271003
I think you want:
select distinct on (object_id) c.*
from (select c.*,
lag(new_status) over (partition by object_id order by mod_date) as prev_ns
from changes c
) c
where prev_ns is distinct from new_status
order by object_id, mod_date desc;
Here is a db<>fiddle.
Upvotes: 3