如何使用 SQL 使用事务日志逐行更新 table

How to Update a table using transaction log row by row using SQL

我有一个 table,它显示工单 ID 及其状态以及在 BI 数据库上分配给谁。这里没有重复,粒度是每张票。

门票Table

Ticket_ID   Status  Assigned_To   Date
001         Open    Team A        01/01/2020 10:01
002         Working Team B        01/01/2020 10:01
003         Open    TeamC         02/01/2020 18:50
004         ResolvedTeam B        02/01/2020 19:22

现在,每天都有一个包含每项更改的事务日志。但是,字段更改显示为如下行。

每日交易记录

Ticket_id       Field_Name      New Value      Date
001           Assigned_to       Team B        02/01/2020 10:23
002           Assigned_to       Team A        02/01/2020 10:23
002           Status            Resolved      02/01/2020 10:24
003           status            Resolved      03/01/2020 10:24
004           Assigned_to       Team C        03/01/2020 13:50
004           Assigned_to       Team A        03/01/2020 13:51
004           Status            Resolved      03/01/2020 13:51

现在我想编写一个更新脚本来根据日志中的新值更新票证 table。考虑到每日事务日志 table 每天都会创建,我认为设置操作将不起作用。我需要 SQL 脚本逐行处理事务日志 table 并使用新值更新票证 table。我知道这是低效的,但是,每天的行数只有数百行。不是几千。

我希望看到的结果如下,其中票证 table 已更新为最新值..

Ticket_ID       Status     Assigned_To  Date
001           Open       Team B       02/01/2020 10:23
002           Resolved   Team A       02/01/2020 10:24
003           Resolved   TeamC        03/01/2020 10:24
004           Resolved   Team A       03/01/2020 13:51

谁能帮帮我。谢谢

您可以使用 distinct on:

获取每列的最新更改
select distinct on (ticket_id, field_name) dtl.*
from daily_transaction_logs dtl
order by ticket_id, date desc;

然后您可以将其汇总以得到每张票一行:

select ticket_id,
       max(new_value) filter (where field_name = 'Assigned_to') as assigned_to,
       max(new_value) filter (where field_name = 'Status') as status,
       max(date) as date
from (select distinct on (ticket_id, field_name) dtl.*
      from daily_transaction_logs dtl
      order by ticket_id, date desc
     ) tf
group by ticket_id;

最后,您可以将其合并到更新中:

update tickets t
    set assigned_to = tt.assigned_to,
        status = tt.status,
        date = tt.date
    from (select ticket_id,
                 max(new_value) filter (where field_name = 'Assigned_to') as assigned_to,
                 max(new_value) filter (where field_name = 'Status') as status,
                 max(date) as date
          from (select distinct on (ticket_id, field_name) dtl.*
                from daily_transaction_logs dtl
                order by ticket_id, date desc
               ) tf
          group by ticket_id
         ) tt
    where tt.ticket_id = t.ticket_id;