【问题标题】:How to Update a table using transaction log row by row using SQL如何使用 SQL 逐行更新使用事务日志的表
【发布时间】:2021-05-06 18:55:33
【问题描述】:

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

票务表

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

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

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

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

谁能帮帮我。谢谢

【问题讨论】:

  • 您是否有可能在同一天有 2 个状态更新?还是分配给“A队”的票,然后在同一天重新分配给“B队”?
  • 是的,有可能。但是我有日期时间戳,因此我们不能同时有两个任务。我更新了日志表
  • 编辑您的问题并显示您想要的结果。

标签: sql postgresql dynamic-sql


【解决方案1】:

您可以使用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;

【讨论】:

  • 我想出了相同的答案,所以我不会复制它。添加指向db<>fiddle 的链接。一个区别 - 您应该在更新中添加合并,因为某些字段可能不会更改(例如,工单 003 的字段 assignment_to)。
  • 谢谢 Julius Tuskenis 和 Gordon。但这不是 Microsoft SQL??它不适合我。当我运行 Gordon 脚本的第一部分时,它显示“打开关键字附近的语法不正确”
  • @DataMan 。 . .不。这是 Postgres,就像标记了问题一样。
  • 谢谢大家。在 MS SQL 中,我创建了一个 CTE 来更新表。如果有人需要,我可以分享代码。但是逻辑真的很有帮助。谢谢
  • @DataMan 。 . .如果您有 SQL Server 问题,请提出 问题。方法会大不相同,这个问题已经得到解答。
猜你喜欢
  • 2021-07-29
  • 2014-05-04
  • 1970-01-01
  • 2010-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-01
  • 1970-01-01
相关资源
最近更新 更多