根据审核记录构建快照表 [英] Building a snapshot table from audit records

查看:161
本文介绍了根据审核记录构建快照表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有以下结构的 Customer 表。

I have a Customer table with the following structure.

CustomerId Name   Address    Phone
1          Joe    123 Main   NULL

我也有审核表,该表跟踪对 Customer 表的更改。

I also have an Audit table that tracks changes to the Customer table.

Id  Entity   EntityId  Field    OldValue      NewValue     Type   AuditDate  
1   Customer 1         Name     NULL          Joe          Add    2016-01-01
2   Customer 1         Phone    NULL          567-54-3332  Add    2016-01-01
3   Customer 1         Address  NULL          456 Centre   Add    2016-01-01
4   Customer 1         Address  456 Centre    123 Main     Edit   2016-01-02
5   Customer 1         Phone    567-54-3332   843-43-1230  Edit   2016-01-03
6   Customer 1         Phone    843-43-1230   NULL         Delete 2016-01-04

我有一个 CustomerHistory 报告表,其中将填充日常的ETL工作。它具有与客户表相同的字段,并带有其他字段 SnapShotDate

I have a CustomerHistory reporting table that will be populated with a daily ETL job. It has the same fields as Customer Table with additional field SnapShotDate.

我需要编写一个查询, Audit 表中的记录,转换并插入到 CustomerHistory 中,如下所示。

I need to write a query that takes the records in Audit table, transforms and inserts into CustomerHistory as seen below.

CustomerId Name   Address      Phone         SnapShotDate
1          Joe    456 Centre   567-54-3332   2016-01-01
1          Joe    123 Main     567-54-3332   2016-01-02
1          Joe    123 Main     843-43-1230   2016-01-03
1          Joe    123 Main     NULL          2016-01-04

我想解决方案将涉及Audit表上的自联接或递归CTE。对于开发此解决方案的任何帮助,我们将不胜感激。

I guess the solution would involve a self-join on Audit table or a recursive CTE. I would appreciate any help with developing this solution.

注意:不幸的是,我无法选择使用触发器或更改审核表模式。不必担心查询性能,因为这将是一个每晚的ETL过程。

Note: Unfortunately, I do not have the option to use triggers or change the Audit table schema. Query performance is not a concern since this will be a nightly ETL process.

推荐答案

您可以使用以下脚本。

You can use below script.

DROP TABLE #tmp

CREATE TABLE #tmp (
    id INT Identity
    , EntityId INT
    , NAME VARCHAR(10)
    , Address VARCHAR(100)
    , Phone VARCHAR(20)
    , Type VARCHAR(10)
    , SnapShotDate DATETIME
    )

;with cte1 as (
select AuditDate, EntityId, Type, [Name], [Address], [Phone]
from 
    (select AuditDate, EntityId, Type, Field, NewValue from #Audit) p
pivot
    (
    max(NewValue)
    for Field in ([Name], [Address], [Phone])
    ) as xx
)
insert into #tmp (EntityId, Name, Address, Phone, Type, SnapShotDate)
select EntityId, Name, Address, Phone, Type, AuditDate
from cte1


-- update NULLs columns with the most recent value
update #tmp
set Name = (select top 1 Name from #tmp tp2 
            where EntityId = tp2.EntityId and Name  is not null 
            order by id desc)
where Name is null

update #tmp
set Address = (select top 1 Address from #tmp tp2 
               where EntityId = tp2.EntityId and Address is not null 
               order by id desc)
where Address is null

update #tmp
set Phone = (select top 1 Phone from #tmp tp2 
             where EntityId = tp2.EntityId and Phone is not null 
             order by id desc)
where Phone is null

要创建测试数据,在以下脚本中使用

To Create Test Data, use below script

CREATE TABLE #Customer (
    CustomerId INT
    , NAME VARCHAR(10)
    , Address VARCHAR(100)
    , Phone VARCHAR(20)
    )

INSERT INTO #Customer
VALUES (1, 'Joe', '123 Main', NULL)

CREATE TABLE #Audit (
    Id INT
    , Entity VARCHAR(50)
    , EntityId INT
    , Field VARCHAR(20)
    , OldValue VARCHAR(100)
    , NewValue VARCHAR(100)
    , Type VARCHAR(10)
    , AuditDate DATETIME
    )

insert into #Audit values
(1,   'Customer', 1,         'Name'     ,NULL            ,'Joe'          ,'Add'    ,'2016-01-01'),
(2,   'Customer', 1,         'Phone'    ,NULL            ,'567-54-3332'  ,'Add'    ,'2016-01-01'),
(3,   'Customer', 1,         'Address'  ,NULL            ,'456 Centre'   ,'Add'    ,'2016-01-01'),
(4,   'Customer', 1,         'Address'  ,'456 Centre'    ,'123 Main'     ,'Edit'   ,'2016-01-02'),
(5,   'Customer', 1,         'Phone'    ,'567-54-3332'   ,'843-43-1230'  ,'Edit'   ,'2016-01-03'),
(6,   'Customer', 1,         'Phone'    ,'843-43-1230'   ,NULL           ,'Delete' ,'2016-01-04'),
(7,   'Customer', 2,         'Name'     ,NULL            ,'Peter'        ,'Add'    ,'2016-01-01'),
(8,   'Customer', 2,         'Phone'    ,NULL            ,'111-222-3333'  ,'Add'    ,'2016-01-01'),
(8,   'Customer', 2,         'Address'  ,NULL            ,'Parthenia'   ,'Add'    ,'2016-01-01')

结果

EntityId    Name    Address     Phone           Type    SnapShotDate
1           Joe     456 Centre  567-54-3332     Add     2016-01-01
1           Joe     123 Main    843-43-1230     Edit    2016-01-02
1           Joe     123 Main    843-43-1230     Edit    2016-01-03
1           Joe     123 Main    843-43-1230     Delete  2016-01-04

这篇关于根据审核记录构建快照表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆