EXCEPT和NOT EXISTS是快速发现数据集之间差异的好方法,但我经常想知道哪些列是不同的,以及它们是如何不同的。
在这些情况下,我发现有用的方法是使用UNPIVOT将列转换为可以逐行比较的键值对。
不过,为了有用,需要有一种方法来匹配你想要比较的记录,在你的例子中,比如社会安全号码或“个人id”:
CREATE TABLE [RealData]
(
[PersonId] INT,
[FirstName] NVARCHAR(100),
[LastName] NVARCHAR(100),
[ProductName] NVARCHAR(100)
)
CREATE TABLE [TempTestData]
(
[PersonId] INT,
[FirstName] NVARCHAR(100),
[LastName] NVARCHAR(100),
[ProductName] NVARCHAR(100)
)
INSERT INTO [RealData] ([PersonId], [FirstName], [LastName], [ProductName])
VALUES
(1, 'Al', 'Bundy', 'Ladies Size 12'),
(2, 'Peggy', 'Bundy', 'TV Guide')
INSERT INTO [TempTestData] ([PersonId], [FirstName], [LastName], [ProductName])
VALUES
(1, 'Al', 'Bundy', 'Ladies Size 13'),
(2, 'Peggy', 'Bundy', 'TV Guide')
UNPIVOT加上一些cte
;WITH RealDataCte AS (
SELECT
'Real Data' AS [DataSource],
unpivotedRealData.*
FROM
(SELECT
CAST([PersonId] AS NVARCHAR(100)) AS [PersonId],
[FirstName],
[LastName],
[ProductName]
FROM [RealData]) AS realData
UNPIVOT
(ColumnValue FOR ColumnName IN ([FirstName], [LastName], [ProductName])) AS unpivotedRealData
),
TempTestDataCte AS (
SELECT
'Temp Test Data' AS [DataSource],
unpivotedDempTestData.*
FROM
(SELECT
CAST([PersonId] AS NVARCHAR(100)) AS [PersonId],
[FirstName],
[LastName],
[ProductName]
FROM [TempTestData]) AS tempTestData
UNPIVOT
(ColumnValue FOR ColumnName IN ([FirstName], [LastName], [ProductName])) AS unpivotedDempTestData
)
SELECT
RealDataCte.[DataSource],
RealDataCte.[ColumnName],
RealDataCte.[ColumnValue],
TempTestDataCte.[DataSource],
TempTestDataCte.[ColumnName],
TempTestDataCte.[ColumnValue],
CASE WHEN RealDataCte.[ColumnValue] <> TempTestDataCte.[ColumnValue] THEN 'YES' ELSE 'NO' END AS ColumnsDiffer
FROM RealDataCte
INNER JOIN
TempTestDataCte
ON RealDataCte.[ColumnName] = TempTestDataCte.[ColumnName]
AND RealDataCte.[PersonId] = TempTestDataCte.[PersonId]
WHERE
RealDataCte.[ColumnValue] <> TempTestDataCte.[ColumnValue]
结果-两种产品是不同的:
如果要在大量的行中比较很多很多列,这是非常好的。
不过,它可能需要一段时间来设置,并且您确实需要将每个列值转换为相同的类型,这可能需要一段时间(注意PersonId的CAST)。
如果数据集非常大,您可能还想使用临时表而不是cte。
SQL小提琴示例