首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >显示历史表中的更改历史

显示历史表中的更改历史
EN

Stack Overflow用户
提问于 2015-04-29 00:40:37
回答 1查看 73关注 0票数 3

我有一个历史表,它由Insert和Update触发器创建。历史记录行包含与插入/更新相同的行。

我被要求做的是通过时间显示每个用户的变化。下面是我的历史表的形式,然后,我创建了一个虚拟的预期结果。

代码语言:javascript
复制
DECLARE @MyTable TABLE
(
    id INT NOT NULL IDENTITY(1,1),
    userId INT NOT NULL,
    locationId INT NOT NULL,
    roleId INT NOT NULL,
    lastUpdateUserId INT NOT NULL,
    lastUpdateDate DATETIME NOT NULL
)


INSERT INTO @MyTable
(userId, locationId, roleId, lastUpdateUserId, lastUpdateDate)
SELECT 1, 1000, 1, 7, GETDATE()+1 UNION
SELECT 2, 1100, 5, 9, GETDATE()+2 UNION
SELECT 2, 1110, 5, 6, GETDATE()+3 UNION
SELECT 1, 1100, 3, 6, GETDATE()+4 UNION
SELECT 4, 1500, 5, 8, GETDATE()+5 UNION
SELECT 7, 1000, 8, 9, GETDATE()+6 UNION
SELECT 7, 1100, 9, 9, GETDATE()+7 UNION
SELECT 1, 1000, 3, 7, GETDATE()+8 UNION
SELECT 9, 1100, 5, 2, GETDATE()+9 UNION
SELECT 9, 1100, 6, 5, GETDATE()+10 

SELECT * FROM @MyTable ORDER BY Id

DECLARE @ExpectedResult TABLE
(
    ChangeType CHAR(1), -- I=Insert, U=Update
    UserId INT,
    ChangeDate DATETIME,
    ChangedByUser INT,
    FieldName VARCHAR(20),
    OldValue INT,
    NewValue INT
)

INSERT INTO @ExpectedResult
(ChangeType, UserId, ChangeDate, ChangedByUser, FieldName, OldValue, NewValue)
SELECT 'I', 1, '2015-APR-30 09:56:28', 7, 'locationId', NULL, 1000 UNION -- Row1
SELECT 'I', 1, '2015-APR-30 09:56:28', 7, 'roleId', NULL, 1 UNION -- Row1
SELECT 'U', 1, '2015-APR-07 10:27:42', 7, 'roleId', 1, 3 UNION -- Row 2
SELECT 'U', 1, '2015-MAY-03 10:27:42', 6, 'locationId', 1000, 1100 UNION -- Row 3
SELECT 'I', 2, '2015-MAY-01 10:27:42', 9, 'roleId', NULL, 5 UNION -- Row5
SELECT 'I', 2, '2015-MAY-01 10:27:42', 9, 'locationId', NULL, 1100 -- Row5

SELECT * FROM @ExpectedResult

@MyTable拥有目前的数据。我正试图将其转化为@ExpectedResults。我们正在报道对roleId和locationId的更改。对于每一项更改,它都需要为每一列设置一个单独的行。因此,在insert上,我们有两行(因为我们监视两个字段的更改)。当一个列被更新时,它需要被表示为一个'U‘线。如果在同一个UPDATE语句中更新了两个字段,那么这将导致@Expected中的两个update行。

我从光标开始,但希望有一种更有效的方法来实现这一点。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-29 01:18:19

要获得单独行上的roleID和locationID,可以使用简单的UNION。

要组合旧值和新值,请使用ROW_NUMBER()窗口函数,如下所示:

代码语言:javascript
复制
;with t as(
    select *,
    ROW_NUMBER() OVER(partition by userid Order BY lastUpdateDate) rn
    from @MyTable
),
a as (
select userId, 'locationId' as fieldname,
locationId as value, lastUpdateUserId, lastUpdateDate, rn
from t
UNION ALL
select userId, 'roleId' as fieldname,
roleId as value, lastUpdateUserId, lastUpdateDate, rn
from t
)
select CASE WHEN a2.userId IS NULL THEN 'I' ELSE 'U' END as ChangeType,
a1.userId, a1.lastUpdateDate, a1.lastUpdateUserId, a1.fieldname, a1.value as newValue, a2.value as oldvalue
FROM a a1 LEFT JOIN a a2
ON a1.userId = a2.userId and a1.fieldname = a2.fieldname
AND a1.rn = a2.rn+1
order by 2,3,5

上面查询中的a1别名包含“新值”,a2包含“旧值”。当使用实际数据时,还需要使用字段名(可能还有表名)进行分区,并将它们连接起来。

结果:

代码语言:javascript
复制
ChangeType userId      lastUpdateDate          lastUpdateUserId fieldname  newValue    oldvalue
---------- ----------- ----------------------- ---------------- ---------- ----------- -----------
I          1           2015-04-30 12:20:59.183 7                locationId 1000        NULL
I          1           2015-04-30 12:20:59.183 7                roleId     1           NULL
U          1           2015-05-03 12:20:59.183 6                locationId 1100        1000
U          1           2015-05-03 12:20:59.183 6                roleId     3           1
U          1           2015-05-07 12:20:59.183 7                locationId 1000        1100
U          1           2015-05-07 12:20:59.183 7                roleId     3           3
I          2           2015-05-01 12:20:59.183 9                locationId 1100        NULL
I          2           2015-05-01 12:20:59.183 9                roleId     5           NULL
U          2           2015-05-02 12:20:59.183 6                locationId 1110        1100
U          2           2015-05-02 12:20:59.183 6                roleId     5           5
I          4           2015-05-04 12:20:59.183 8                locationId 1500        NULL
I          4           2015-05-04 12:20:59.183 8                roleId     5           NULL
I          7           2015-05-05 12:20:59.183 9                locationId 1000        NULL
I          7           2015-05-05 12:20:59.183 9                roleId     8           NULL
U          7           2015-05-06 12:20:59.183 9                locationId 1100        1000
U          7           2015-05-06 12:20:59.183 9                roleId     9           8
I          9           2015-05-08 12:20:59.183 2                locationId 1100        NULL
I          9           2015-05-08 12:20:59.183 2                roleId     5           NULL
U          9           2015-05-09 12:20:59.183 5                locationId 1100        1100
U          9           2015-05-09 12:20:59.183 5                roleId     6           5

(20 row(s) affected)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29932394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档