oracle 根据不同日期列的上一行更新日期列的当前行

dkqlctbz  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(145)

请帮助在Oracle SQL中实现这一点。
我有如下的表格结构,

create table temp_t 
(
    rule_id number, 
    start_datetime timestamp, 
    end_datetime timestamp,
    last_update timestamp 
);

insert into temp_t values (2345,TO_TIMESTAMP('2023-10-02 15:22:37','YYYY-MM-DD HH24:MI:SS'),null,null);
insert into temp_t values (2345,TO_TIMESTAMP('2023-10-02 15:18:36','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2023-10-02 15:22:36','YYYY-MM-DD HH24:MI:SS'),null);
insert into temp_t values (2345,TO_TIMESTAMP('2023-10-02 15:15:18','YYYY-MM-DD HH24:MI:SS'),null,null);
insert into temp_t values (2345,TO_TIMESTAMP('2023-10-02 15:11:02','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2023-10-02 15:12:10','YYYY-MM-DD HH24:MI:SS'),null);
insert into temp_t values (2345,TO_TIMESTAMP('2023-10-02 14:03:02','YYYY-MM-DD HH24:MI:SS'),null,null);

表格数据:

预期结果如下所示,END_DATETIME上的NULL值将根据前一行的START_DATETIME列在负1秒内更新。不应更新END_DATETIME NULL的最新行。

RULE_ID | START_DATETIME                 | END_DATETIME                  |
-----------------------------------------------------------------------
2345    |02-OCT-23 03.22.37.000000000 PM |  NULL
2345    |02-OCT-23 03.18.36.000000000 PM |  02-OCT-23 03.22.36.000000000 PM
2345    |02-OCT-23 03.15.18.000000000 PM |  02-OCT-23 03.18.35.000000000 PM
2345    |02-OCT-23 03.11.02.000000000 PM |  02-OCT-23 03.12.10.000000000 PM
2345    |02-OCT-23 02.03.02.000000000 PM |  02-OCT-23 03.11.01.000000000 PM
qybjjes1

qybjjes11#

将结束时间重新定义为下一行的开始时间,以获得无间隙序列:

SELECT rule_id,
       start_datetime,
       LEAD(start_datetime) OVER (PARTITION BY rule_id ORDER BY start_datetime) AS end_datetime
  FROM temp_t

或者,如果您希望现有的end_datetime值是正确的,即使下一个开始时间是在未来,您可以保留现有的值,仅在它们为NULL时替换它们:

SELECT rule_id,
       start_datetime,
       NVL(end_datetime,LEAD(start_datetime) OVER (PARTITION BY rule_id ORDER BY start_datetime)) AS end_datetime
  FROM temp_t

如果你想更新表而不是用SELECT拉取,那么你甚至不需要窗口函数:

UPDATE temp_t t1
   SET end_datetime = (SELECT MIN(t2.start_datetime)
                         FROM temp_t t2
                        WHERE t2.rule_id = t1.rule_id
                          AND t2.start_datetime > t1.start_datetime)
 WHERE end_datetime IS NULL;

相关问题