我有2个表-一个表具有最新记录(#Director表),另一个表(#DirectorAudit)具有记录发生更改的记录。 AuditId是完成的更改的顺序
需要具有以下输出-
获得此输出的最佳方法是什么。
请在下面找到当前代码以获取输出,但我对此不满意。我们可以替换while循环(没有游标plz)或其他逻辑的任何替代解决方案。
我们非常感谢您的帮助。非常感谢。
SET NOCOUNT ON;
IF OBJECT_id('tempdb..#a') IS NOT NULL DROP TABLE #a
IF OBJECT_id('tempdb..#b') IS NOT NULL DROP TABLE #b
IF OBJECT_id('tempdb..#c') IS NOT NULL DROP TABLE #c
IF OBJECT_id('tempdb..#d') IS NOT NULL DROP TABLE #d
IF OBJECT_id('tempdb..#DirectorAudit') IS NOT NULL DROP TABLE #DirectorAudit
IF OBJECT_id('tempdb..#Director') IS NOT NULL DROP TABLE #Director
Create table #DirectorAudit(AuditId TINYINT IDENTITY(1,1),DirectorID INT,[Name] varchar(200),Code varchar(5))
INSERT INTO #DirectorAudit(DirectorID,[Name],Code)
SELECT 541,'Steven','A'
UNION
SELECT 541,'Roger','A'
UNION
SELECT 541,'Mathew','A'
UNION
SELECT 541,'Mathew','I'
Create table #Director(DirectorID INT,[Name] varchar(200),Code varchar(5))
INSERT INTO #Director(DirectorID,[Name],Code)
SELECT 541,'David','A'
CREATE TABLE #d (DirectorID INT ,FieldName VARCHAR(100), OldValue VARCHAR(4000), NewValue VARCHAR(4000), AuditID int)
CREATE TABLE #b (DirectorID INT, Oldvalue VARCHAR(4000),oldCode VARCHAR(200),AuditId INT)
CREATE TABLE #c (DirectorID INT, NewValue VARCHAR(4000),oldCode VARCHAR(200),AuditId INT)
DECLARE @oldValue VARCHAR(200),
@Code VARCHAR(200),
@newValue VARCHAR(200),
@newCode VARCHAR(200),
@DirectorID INT = 541
SELECT Row_Number() over(order by AuditId asc) as ID,
a.DirectorID,
a.Name as NewName,
b.Name as OldName,
a.Code as NewCode,
b.Code as oldCode,
b.AuditID
INTO #a
FROM #Director a
INNER JOIN #DirectorAudit b ON a.DirectorID = b.DirectorID
WHERE b.DirectorID = @DirectorID
order by b.AuditId
DECLARE @count INT =1
DECLARE @init INT = 1
DECLARE @tmp_AuditId INT
DECLARE @tmp_NextAuditID INT
SELECT @count = COUNT(*) FROM #a
WHILE @count >= @init
BEGIN
SELECT @tmp_AuditId = AuditId from #a WHERE Id = @init
select @tmp_NextAuditID = AuditId from #a WHERE Id = @init+1
IF @count =1 SET @tmp_NextAuditID = @tmp_AuditId
SELECT @OldValue = OldName,
@Code = oldCode
from #a
where AuditID = @tmp_AuditId
select @newValue = OldName,
@newCode = oldCode
from #a
where AuditID = @tmp_NextAuditID
INSERT INTO #b(DirectorID, OldValue,oldCode, AuditID)
select DirectorID, @OldValue,@Code, AuditID
FROM #a
WHERE AuditId = @tmp_AuditId
IF @count <> @init
BEGIN
INSERT INTO #c(DirectorID, NewValue,oldCode, AuditID)
select DirectorID, @newValue,@newCode, @tmp_AuditId
FROM #a
WHERE AuditId = @tmp_NextAuditID
END
ELSE
BEGIN
INSERT INTO #c(DirectorID, NewValue, oldCode,AuditID)
select E.DirectorID, e.Name,e.Code, a.AuditID
FROM #Director e
INNER JOIN #a a ON e.DirectorID = a.DirectorID
WHERE AuditId = @tmp_NextAuditID
END
SET @init = @init + 1
END
/*
select * from #a
SELECT * FROM #b
SELECT * FROM #c
*/
INSERT INTO #d(DirectorID,FieldName, OldValue, NewValue, AuditID)
SELECT DirectorID,FieldName, OldValue, NewValue, AuditID
FROM (
SELECT c.DirectorID,'Name' as FieldName, c.OldValue as OldValue, d.NewValue as NewValue, c.AuditID
FROM #b as c
inner join #c as d ON c.AuditId = d.AuditId
UNION
SELECT c.DirectorID,'Code' as FieldName, c.oldCode as OldValue, d.oldCode as NewValue, c.AuditID
FROM #b as c
inner join #c as d ON c.AuditId = d.AuditId
)x
order by x.AuditID
select a.DirectorID,FieldName, OldValue, NewValue
from #d a
where OLdValue <> NewValue
order by a.FieldName desc
答案 0 :(得分:3)
这里是您仅需提及关键字段的一种方法。在这种情况下,AutidID和DirectorID
交叉应用B会将记录转换为XML
Cross Apply C将动态取消透视数据(不包括指定的列)
示例
;with cte as (
Select A.AuditID
,A.DirectorID
,C.*
,NewValue = lag(OldValue,1,OldValue) over (Partition By DirectorID,Field Order by case when AuditID is null then 0 else 1 end,AuditID desc)
From (
Select * from #DirectorAudit
Union All
Select null,* from #Director
) A
Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)
Cross Apply (
Select Field = a.value('local-name(.)','varchar(100)')
,OldValue = a.value('.','varchar(max)')
From B.XMLData.nodes('/row') as C1(n)
Cross Apply C1.n.nodes('./@*') as C2(a)
Where a.value('local-name(.)','varchar(100)') not in ('AuditId','DirectorID','OtherColumnsToExclude')
) C
)
Select *
From cte
Where OldValue<>NewValue
Order by Field,AuditID
返回
AuditID DirectorID Field OldValue NewValue
1 541 Code A I
2 541 Code I A
2 541 Name Mathew Roger
3 541 Name Roger Steven
4 541 Name Steven David
编辑-要求替代
;with cte as (
Select A.AuditID
,A.DirectorID
,B.*
,NewValue = lag(OldValue,1,OldValue) over (Partition By DirectorID,Field Order by case when AuditID is null then 0 else 1 end,AuditID desc)
From (
Select * from #DirectorAudit
Union All
Select null,* from #Director
) A
Cross Apply ( values ('Name',Name)
,('Code',Code)
) B(Field,OldValue)
)
Select *
From cte
Where OldValue<>NewValue
Order by Field,AuditID