首页 > 解决方案 > 选择给定值更改的最后一行

问题描述

我想选择最后一行(按mod_date),其中列new_status与给定的上一个条目不同object_id

起初我尝试使用 row_number 但没有成功,后来我想出了超前/滞后功能,我认为我更接近解决方案但仍然不是理想的结果。

这是代码和小提琴: 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

1001 和 1003 的输出很好,对于 1002,它应该是状态为 0 的行。

感谢任何帮助和建议!

标签: sqlpostgresqlselect

解决方案


我想你想要:

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;

是一个 db<>fiddle。


推荐阅读