我有一张桌子,看起来像这样

表1

LOG_ID DATE ROOM USER MINUTES ROOM_IN ROOM_OUT TURNAROUND
12345 08/01/23 1 DOE, JANE 50 7:35 8:30 0
12345 08/01/23 1 DOE, JANE 5 7:35 8:30 0
67890 08/01/23 1 DOE, JOHN 20 9:04 9:24 34
12111 08/01/23 1 PATEL, NANCY 28 10:52 11:20 88
12222 08/01/23 1 DREW, AMBER 100 11:41 15:21 21

我注意到周转时间适用于周转后的原木,而不是它之前的原木.

例如,日志(log)12345在上午8:30结束,日志(log)67890在上午9:04开始34分钟的周转时间应应用于日志(log)12345,而不是上表所示的日志(log)67890.

表2如下所示:

LOG_ID PRECEDING_LOG_ID ROOM_OUT_TO_IN
67890 12345 34
12222 12111 21
12111 67890 88

我创建了以下CTE

CORRECT_TAT AS 
(
    SELECT tb2.PRECEDING_LOG_ID AS PRE_LOG_ID, tb1.TURNAROUND AS CORRECT_ACTUAL_TAT_2
    FROM tb1
    LEFT OUTER JOIN tb2 ON tb1.LOG_ID = tb2.LOG_ID
),
CORRECT_TAT_2 AS 
(
    SELECT 
        tb1.*, 
        NVL(CT.CORRECT_ACTUAL_TAT_2, 0) AS CORRECT_ACTUAL_TAT_2,
        NVL(CT.CAPPED_ACTUAL_TAT_2, 0) AS CAPPED_ACTUAL_TAT_2
    FROM
        tb1
    LEFT OUTER JOIN 
        CORRECT_TAT CT ON tb1.LOG_ID = CT.PRE_LOG_ID
)

我希望创建一个临时表,将tb2.PRECEDING_LOG_ID作为表的主键,并提取tb1.TURNAROUND.

因此,CTE表将如下所示:

PRE_LOG_ID CORRECT_ACTUAL_TAT_2
null null
12345 34
12111 21
67890 88

我的理想输出是:

LOG_ID DATE ROOM USER MINUTES ROOM_IN ROOM_OUT TURNAROUND
12345 08/01/23 1 DOE, JANE 50 7:35 8:30 34
12345 08/01/23 1 DOE, JANE 5 7:35 8:30 0
67890 08/01/23 1 DOE, JOHN 20 9:04 9:24 88
12111 08/01/23 1 PATEL, NANCY 28 10:52 11:20 21
12222 08/01/23 1 DREW, AMBER 100 11:41 15:21 0

对于重复的日志(log)(第1行和第2行),是否可以应用一次周转?因为,扭亏为盈只发生一次.

我的代码的问题是它会导致重复.

例如,日志(log)67890在tb1中只出现一次,但我的代码生成以下内容:

LOG_ID DATE ROOM USER MINUTES ROOM_IN ROOM_OUT TURNAROUND
12345 08/01/23 1 DOE, JANE 50 7:35 8:30 34
12345 08/01/23 1 DOE, JANE 5 7:35 8:30 34
67890 08/01/23 1 DOE, JOHN 20 9:04 9:24 0
67890 08/01/23 1 DOE, JOHN 20 9:04 9:24 88

行数不会随着CTE right_tat的变化而改变,但我使用cte right_tat_2得到的行数更多,所以我认为这就是问题所在.

数据通常不会以任何方式排序.

我很感激任何人的帮助,我试着让数据尽可能简单.

推荐答案

您的表已经包含您想要的数据,但周转不在它所属的行中,而总是在它后面的行中.

使用LEAD获取下一行的数据:

select
  log_id, date, room, user, minutes, room_in, room_out,
  nvl(lead (turnaround) over (order by room, date, room_in), 0) as turnaround
from tb1
order by room, date, lpad(room_in, 5, '0');

如果要更新行,可以在MERGE语句中使用以下查询:

merge into tb1 using
(
  select
    log_id, dt, room, usr, minutes, room_in, room_out,
    nvl(lead(turnaround) over (order by room, dt, lpad(room_in, 5, '0')), 0) as turnaround
  from tb1
) correction on (correction.rowid = tb1.rowid)
when matched then update set tb1.turnaround = correction.turnaround;

演示:https://dbfiddle.uk/8CnZ0dKi

Sql相关问答推荐

创建每小时重置的序列号

有没有办法在每次计算每一行的数据时更新2个值?

如何利用单列历史SQLsnowflake获得合并结果

查找表中特定值的上次更新日期

将结果从一列转换为两行或更多

基于是否具有某些数据的关联表覆盖SELECT语句中的列值

同时插入和更新记录

存储过程太慢

如何在android房间中进行多个加入

GRAFANA 数据库查询错误:pq:列名称不存在

如何根据创建日期查找两个表中最接近的记录?

如何使用最后一个非 NULL 值在 PostgreSQL 列中填充 NULL 值

如何查询自引用 comments 表以查找带有回复的 comments ,并按最新回复排序?

Oracle SQL:通过将日期与另一个表行进行比较来 Select 值

计算 ID 满足条件的次数

PostgreSQL-用第一个非空填充以前的值

BigQuery Pivot 遗漏行

多列上的 SQL UNIQUE 约束 - 它们的组合必须是唯一的还是至少其中之一?

SQL中所有先前日期的累计总和

删除具有相同 ID 的重复记录 - Postgresql