为了获得所提到的输出,应该对sql查询进行哪些更改?
我有一张这样的桌子:为了获得所提到的输出,应该对sql查询进行哪些更改?,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有一张这样的桌子: CREATE TABLE AuditTrail ( AuditTrailId Integer, OldValue xml, NewValue xml ) INSERT INTO **AuditTrail** SELECT 107 AS AuditTrailId, '<Root><NHL_DARCR><NHLLoanId>75
CREATE TABLE AuditTrail
(
AuditTrailId Integer,
OldValue xml,
NewValue xml
)
INSERT INTO **AuditTrail**
SELECT 107 AS AuditTrailId,
'<Root><NHL_DARCR><NHLLoanId>750</NHLLoanId><Amount>909.00</Amount><ModifiedBy>2001</ModifiedBy><ModifiedDate>2018-02-01T18:19:49.700</ModifiedDate></NHL_DARCR><NHL_DARCR><NHLLoanId>77</NHLLoanId><Amount>404.00</Amount><ModifiedBy>2001</ModifiedBy><ModifiedDate>2018-02-02T09:32:52.137</ModifiedDate></NHL_DARCR></Root>' AS OldValue,
'<Root><NHL_DARCR><NHLLoanId>750</NHLLoanId><Amount>101.00</Amount><ModifiedBy>2001</ModifiedBy><ModifiedDate>2018-02-02T09:33:22.447</ModifiedDate></NHL_DARCR><NHL_DARCR><NHLLoanId>77</NHLLoanId><Amount>303.00</Amount><ModifiedBy>2001</ModifiedBy><ModifiedDate>2018-02-02T09:33:22.447</ModifiedDate></NHL_DARCR></Root>' AS NewValue
为了获得上述输出,我尝试了以下方法:
SELECT DISTINCT
AuditIdOld
, C2_Old AS Column_Name
, ISNULL(C3_Old, '-') Old_Value
, ISNULL(C3_New, '-') New_Value
FROM
(
SELECT distinct
AuditTrailId AuditIdOld
, x.value('local-name(..)', 'varchar(50)') AS C1_Old
, x.value('local-name(.)', 'varchar(50)') AS C2_Old
, x.value('.', 'varchar(max)') AS C3_Old
, x.value('(text())[1]','varchar(32)') as xNHLLoanID
FROM AuditTrail
CROSS APPLY OldValue.nodes('Root//*') e(x)
WHERE oldvalue IS NOT NULL
AND x.value('local-name(..)', 'varchar(50)') <> 'Root'
) t1
JOIN
(
SELECT DISTINCT AuditTrailId AuditIdNew
, x.value('local-name(..)'
, 'varchar(50)') AS C1_New, x.value('local-name(.)'
, 'varchar(50)') AS C2_New, x.value('.',
'varchar(max)') AS C3_New
, x.value('(text())[1]','varchar(32)') as xNHLLoanID
FROM AuditTrail
CROSS APPLY NewValue.nodes('Root//*') e(x)
WHERE NewValue IS NOT NULL
AND x.value('local-name(..)', 'varchar(50)') <> 'Root'
) t2
ON AuditIdOld = AuditIdNew
and t1.C2_Old = t2.C2_New
我仍然没有得到所需的输出。有人能帮我解答这个问题吗?老实说,这太麻烦了。它涉及数据的取消激发和xml解析 这是我的解决方案,然而,这只是基于我们这里的少量数据。我猜还有很多,我不知道它是否适用于你可能有更多字段的所有内容,例如,我没有在值的CTE字段中包含这些内容,因为我不知道它们是什么 如果您对它在做什么有任何疑问,我很乐意回答,但您需要支持对它所做的任何更改:
USE Sandbox;
GO
CREATE TABLE AuditTrail (AuditTrailId int,
OldValue xml,
NewValue xml);
GO
INSERT INTO AuditTrail
SELECT 107 AS AuditTrailId,
'<Root><NHL_DARCR><NHLLoanId>750</NHLLoanId><Amount>909.00</Amount><ModifiedBy>2001</ModifiedBy><ModifiedDate>2018-02-01T18:19:49.700</ModifiedDate></NHL_DARCR><NHL_DARCR><NHLLoanId>77</NHLLoanId><Amount>404.00</Amount><ModifiedBy>2001</ModifiedBy><ModifiedDate>2018-02-02T09:32:52.137</ModifiedDate></NHL_DARCR></Root>' AS OldValue,
'<Root><NHL_DARCR><NHLLoanId>750</NHLLoanId><Amount>101.00</Amount><ModifiedBy>2001</ModifiedBy><ModifiedDate>2018-02-02T09:33:22.447</ModifiedDate></NHL_DARCR><NHL_DARCR><NHLLoanId>77</NHLLoanId><Amount>303.00</Amount><ModifiedBy>2001</ModifiedBy><ModifiedDate>2018-02-02T09:33:22.447</ModifiedDate></NHL_DARCR></Root>' AS NewValue;
GO
WITH Fields AS (
SELECT *
FROM (VALUES ('NHLLoanId',1),('Amount',2),('ModifiedBy',3),('ModifiedDate',4)) V(FieldName, SortOrder)),
OldValues AS (
SELECT A.AuditTrailId,
OV.D.value('(NHLLoanId/text())[1]','varchar(50)') AS NHLLoadId,
OV.D.value('(Amount/text())[1]','varchar(50)') AS Amount,
OV.D.value('(ModifiedBy/text())[1]','varchar(50)') AS ModifiedBy,
OV.D.value('(ModifiedDate/text())[1]','varchar(50)') AS ModifiedDate
FROM AuditTrail A
CROSS APPLY A.OldValue.nodes('/Root/NHL_DARCR') OV(D)),
NewValues AS(
SELECT A.AuditTrailId,
NV.D.value('(NHLLoanId/text())[1]','varchar(50)') AS NHLLoadId,
NV.D.value('(Amount/text())[1]','varchar(50)') AS Amount,
NV.D.value('(ModifiedBy/text())[1]','varchar(50)') AS ModifiedBy,
NV.D.value('(ModifiedDate/text())[1]','varchar(50)') AS ModifiedDate
FROM AuditTrail A
CROSS APPLY A.NewValue.nodes('/Root/NHL_DARCR') NV(D)),
OldUnPivot AS(
SELECT OV.AuditTrailId,
F.FieldName AS Column_Name,
F.SortOrder,
OV.NHLLoadId,
CASE F.FieldName WHEN 'NHLLoanId' THEN OV.NHLLoadId
WHEN 'Amount' THEN OV.Amount
WHEN 'ModifiedBy' THEN OV.ModifiedBy
WHEN 'ModifiedDate' THEN OV.ModifiedDate END AS Old_Value
FROM Fields F
CROSS JOIN OldValues OV),
NewUnPivot AS(
SELECT NV.AuditTrailId,
F.FieldName AS Column_Name,
F.SortOrder,
NV.NHLLoadId,
CASE F.FieldName WHEN 'NHLLoanId' THEN NV.NHLLoadId
WHEN 'Amount' THEN NV.Amount
WHEN 'ModifiedBy' THEN NV.ModifiedBy
WHEN 'ModifiedDate' THEN NV.ModifiedDate END AS New_Value
FROM Fields F
CROSS JOIN NewValues NV)
SELECT OUP.AuditTrailId,
OUP.Column_Name,
OUP.Old_Value,
NUP.New_Value
FROM OldUnPivot OUP
JOIN NewUnPivot NUP ON OUP.AuditTrailId = NUP.AuditTrailId
AND OUP.NHLLoadId = NUP.NHLLoadId
AND OUP.Column_Name = NUP.Column_Name
WHERE OUP.Column_Name IS NOT NULL
ORDER BY AuditTrailID ASC,
OUP.NHLLoadId DESC,
OUP.SortOrder ASC;
GO
DROP TABLE AuditTrail;
老实说,这真是一团糟。它涉及数据的取消激发和xml解析 这是我的解决方案,然而,这只是基于我们这里的少量数据。我猜还有很多,我不知道它是否适用于你可能有更多字段的所有内容,例如,我没有在值的CTE字段中包含这些内容,因为我不知道它们是什么 如果您对它在做什么有任何疑问,我很乐意回答,但您需要支持对它所做的任何更改:
USE Sandbox;
GO
CREATE TABLE AuditTrail (AuditTrailId int,
OldValue xml,
NewValue xml);
GO
INSERT INTO AuditTrail
SELECT 107 AS AuditTrailId,
'<Root><NHL_DARCR><NHLLoanId>750</NHLLoanId><Amount>909.00</Amount><ModifiedBy>2001</ModifiedBy><ModifiedDate>2018-02-01T18:19:49.700</ModifiedDate></NHL_DARCR><NHL_DARCR><NHLLoanId>77</NHLLoanId><Amount>404.00</Amount><ModifiedBy>2001</ModifiedBy><ModifiedDate>2018-02-02T09:32:52.137</ModifiedDate></NHL_DARCR></Root>' AS OldValue,
'<Root><NHL_DARCR><NHLLoanId>750</NHLLoanId><Amount>101.00</Amount><ModifiedBy>2001</ModifiedBy><ModifiedDate>2018-02-02T09:33:22.447</ModifiedDate></NHL_DARCR><NHL_DARCR><NHLLoanId>77</NHLLoanId><Amount>303.00</Amount><ModifiedBy>2001</ModifiedBy><ModifiedDate>2018-02-02T09:33:22.447</ModifiedDate></NHL_DARCR></Root>' AS NewValue;
GO
WITH Fields AS (
SELECT *
FROM (VALUES ('NHLLoanId',1),('Amount',2),('ModifiedBy',3),('ModifiedDate',4)) V(FieldName, SortOrder)),
OldValues AS (
SELECT A.AuditTrailId,
OV.D.value('(NHLLoanId/text())[1]','varchar(50)') AS NHLLoadId,
OV.D.value('(Amount/text())[1]','varchar(50)') AS Amount,
OV.D.value('(ModifiedBy/text())[1]','varchar(50)') AS ModifiedBy,
OV.D.value('(ModifiedDate/text())[1]','varchar(50)') AS ModifiedDate
FROM AuditTrail A
CROSS APPLY A.OldValue.nodes('/Root/NHL_DARCR') OV(D)),
NewValues AS(
SELECT A.AuditTrailId,
NV.D.value('(NHLLoanId/text())[1]','varchar(50)') AS NHLLoadId,
NV.D.value('(Amount/text())[1]','varchar(50)') AS Amount,
NV.D.value('(ModifiedBy/text())[1]','varchar(50)') AS ModifiedBy,
NV.D.value('(ModifiedDate/text())[1]','varchar(50)') AS ModifiedDate
FROM AuditTrail A
CROSS APPLY A.NewValue.nodes('/Root/NHL_DARCR') NV(D)),
OldUnPivot AS(
SELECT OV.AuditTrailId,
F.FieldName AS Column_Name,
F.SortOrder,
OV.NHLLoadId,
CASE F.FieldName WHEN 'NHLLoanId' THEN OV.NHLLoadId
WHEN 'Amount' THEN OV.Amount
WHEN 'ModifiedBy' THEN OV.ModifiedBy
WHEN 'ModifiedDate' THEN OV.ModifiedDate END AS Old_Value
FROM Fields F
CROSS JOIN OldValues OV),
NewUnPivot AS(
SELECT NV.AuditTrailId,
F.FieldName AS Column_Name,
F.SortOrder,
NV.NHLLoadId,
CASE F.FieldName WHEN 'NHLLoanId' THEN NV.NHLLoadId
WHEN 'Amount' THEN NV.Amount
WHEN 'ModifiedBy' THEN NV.ModifiedBy
WHEN 'ModifiedDate' THEN NV.ModifiedDate END AS New_Value
FROM Fields F
CROSS JOIN NewValues NV)
SELECT OUP.AuditTrailId,
OUP.Column_Name,
OUP.Old_Value,
NUP.New_Value
FROM OldUnPivot OUP
JOIN NewUnPivot NUP ON OUP.AuditTrailId = NUP.AuditTrailId
AND OUP.NHLLoadId = NUP.NHLLoadId
AND OUP.Column_Name = NUP.Column_Name
WHERE OUP.Column_Name IS NOT NULL
ORDER BY AuditTrailID ASC,
OUP.NHLLoadId DESC,
OUP.SortOrder ASC;
GO
DROP TABLE AuditTrail;
考虑阅读,考虑阅读好,但你理解它,“死猫?好,但你明白吗,”DeadCat?