为了获得所提到的输出,应该对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?