oracle 使用左外联接更正Row+1列中的值时重复

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

我有一张table,看起来像这样
表1
| 联系我们|日期|房间|用户|分钟|房间_在|客房_外出|周转|
| --|--|--|--|--|--|--|--|
| 12345 |2018年01月08日| 1 |简·多伊| 50 |七点三十五分|八点半| 0 |
| 12345 |2018年01月08日| 1 |简·多伊| 5 |七点三十五分|八点半| 0 |
| 67890 |2018年01月08日| 1 |约翰·道尔| 20 |九点零四分|九点二十四分| 34 |
| 12111 |2018年01月08日| 1 |南希·帕特尔| 28 |十点五十二分|十一点二十分| 88 |
| 12222 |2018年01月08日| 1 |DREW,琥珀色| 100 |十一点四十一分|十五点二十一分| 21 |
我注意到,周转时间应用于周转之后的日志,而不是应用于周转之前的日志。
例如,日志12345在上午8:30结束,日志67890在上午9:04开始。34分钟周转应适用于日志12345,而不是上表所示的日志67890。
表2看起来像这样:
| 联系我们|PRECEDING_ID|房间输出到输入|
| --|--|--|
| 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_ID_ID| CORRECT_ACTUAL_TAT_2|
| --|--|
| null| null|
| 12345 | 34 |
| 12111 | 21 |
| 67890 | 88 |
我的理想输出:
| 联系我们|日期|房间|用户|分钟|房间_在|客房_外出|周转|
| --|--|--|--|--|--|--|--|
| 12345 |2018年01月08日| 1 |简·多伊| 50 |七点三十五分|八点半| 34 |
| 12345 |2018年01月08日| 1 |简·多伊| 5 |七点三十五分|八点半| 0 |
| 67890 |2018年01月08日| 1 |约翰·道尔| 20 |九点零四分|九点二十四分| 88 |
| 12111 |2018年01月08日| 1 |南希·帕特尔| 28 |十点五十二分|十一点二十分| 21 |
| 12222 |2018年01月08日| 1 |DREW,琥珀色| 100 |十一点四十一分|十五点二十一分| 0 |
对于重复的日志(第1行和第2行),是否可以应用一次周转?因为,转机只有一次。
我的代码的问题是它会导致重复。
例如,Log 67890在tb 1中只出现一次,但我的代码生成以下内容:
| 联系我们|日期|房间|用户|分钟|房间_在|客房_外出|周转|
| --|--|--|--|--|--|--|--|
| 12345 |2018年01月08日| 1 |简·多伊| 50 |七点三十五分|八点半| 34 |
| 12345 |2018年01月08日| 1 |简·多伊| 5 |七点三十五分|八点半| 34 |
| 67890 |2018年01月08日| 1 |约翰·道尔| 20 |九点零四分|九点二十四分| 0 |
| 67890 |2018年01月08日| 1 |约翰·道尔| 20 |九点零四分|九点二十四分| 88 |
行的数量不会随着CTE CORRECT_达特而改变,但是我得到了CTE CORRECT_TAT_2的更多行,所以我相信这就是它出错的地方。
数据通常不以任何方式排序。
我感谢任何帮助,我试图使数据尽可能简单。

fjaof16o

fjaof16o1#

你的表已经包含了你想要的数据,但是周转不是在它所属的行中,而是总是在它后面的行中。
使用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

相关问题