在 SQL 服务器中的两个表之间查找不同的值

Find different values between two tables in SQL Server

我创建了两个具有相同字段但可能具有不同值的 table:

create table TableA
(
    rowid int Identity(1,1),
    FirstName varchar(100),
    LastName varchar(100),
    Phone varchar(100)
)
create table TableB
(
    rowid int Identity(1,1),
    FirstName varchar(100),
    LastName varchar(100),
    Phone varchar(100)
)

我用一些值填充了 tables 以便能够测试:

insert into TableA(FirstName, LastName, Phone)
values('JORGE','LUIS','41514493')
insert into TableA(FirstName, LastName, Phone)
values('JUAN','ROBERRTO','41324133')
insert into TableA(FirstName, LastName, Phone)
values('ALBERTO','JOSE','41514461')
insert into TableA(FirstName, LastName, Phone)
values('JULIO','ESTUARDO','56201550')
insert into TableA(FirstName, LastName, Phone)
values('ALFREDO','JOSE','32356654')
insert into TableA(FirstName, LastName, Phone)
values('LUIS','FERNANDO','98596210')

insert into TableB(FirstName, LastName, Phone)
values('JORGE','LUIS','41514493')
insert into TableB(FirstName, LastName, Phone)
values('JUAN','ROBERTO','41324132')
insert into TableB(FirstName, LastName, Phone)
values('ALBERTO','JOSE','41514461')
insert into TableB(FirstName, LastName, Phone)
values('JULIO','ESTUARDO','56201551')
insert into TableB(FirstName, LastName, Phone)
values('ALFRIDO','JOSE','32356653')
insert into TableB(FirstName, LastName, Phone)
values('LUIS','FERNANDOO','98596210')

如果我在两个 table 上都执行 select * ,则存在具有与图像不同值的行...

enter image description here

所以我需要在临时 table 中插入两个 table 之间不相同的每个值的差异,并为每个差异插入一行,临时 table 会有这个...

create table #diference 
(
    diference varchar(300)
)

我试图避免使用 when 或使用游标,所以我创建了这个查询来插入差异:

insert into #diference (diference)
SELECT  Case
        when a.FirstName <> b.FirstName then 'The last name is not the same in A (' + a.FirstName + ') with B (' + b.FirstName + ')' 
        when a.LastName <> b.LastName then 'The last name is not the same in A (' + a.LastName + ') with B (' + b.LastName + ')'
        when a.Phone <> b.Phone then 'The phone is not the same in A (' + a.Phone + ') with B ( ' + b. Phone + ' )'
        End as diference
FROM    TableA a INNER JOIN TableB b ON A.rowid = B.rowid
WHERE   a.FirstName <> b.FirstName 
        or a.LastName <> b.LastName
        or a.Phone <> b.Phone

但它只是在比较中插入有多个不同的第一个不匹配项,我需要插入两个不匹配项,如果有更多不匹配项甚至更多,并为每个不匹配项创建一行。任何人都会认为更好处理方法....

不需要任何额外的 table。联合 tables,因为联合只有 select distinct 值,你会得到唯一的行。任何具有相同数据的重复行都将被忽略。查询就像

select * from TableA
union
select * from TableB

这是处理两个表差异的通用方法。

我们只需要知道他们的主键列即可。

它基于 JSON,将从 SQL Server 2016 开始运行。

SQL

-- DDL and sample data population, start
DECLARE @TableA table (rowid int Identity(1,1), FirstName varchar(100), LastName varchar(100), Phone varchar(100));
DECLARE @TableB table (rowid int Identity(1,1), FirstName varchar(100), LastName varchar(100), Phone varchar(100));

insert into @TableA(FirstName, LastName, Phone) VALUES
('JORGE','LUIS','41514493'),
('JUAN','ROBERRTO','41324133'),
('ALBERTO','JOSE','41514461'),
('JULIO','ESTUARDO','56201550'),
('ALFREDO','JOSE','32356654'),
('LUIS','FERNANDO','98596210');

insert into @TableB(FirstName, LastName, Phone) VALUES
('JORGE','LUIS','41514493'),
('JUAN','ROBERTO','41324132'),
('ALBERTO','JOSE','41514461'),
('JULIO','ESTUARDO','56201551'),
('ALFRIDO','JOSE','32356653'),
('LUIS','FERNANDOO','98596210');
-- DDL and sample data population, end

SELECT rowid
      ,[key] AS [column]
      ,Org_Value = MAX( CASE WHEN Src=1 THEN Value END)
      ,New_Value = MAX( CASE WHEN Src=2 THEN Value END)
FROM (
        SELECT Src=1
              ,rowid 
              ,B.*
         FROM @TableA A
         CROSS APPLY ( SELECT [Key]
                             ,Value
                       FROM OpenJson( (SELECT A.* For JSON Path,Without_Array_Wrapper,INCLUDE_NULL_VALUES)) 
                     ) AS B
        UNION ALL
        SELECT Src=2
              ,rowid 
              ,B.*
         FROM @TableB A
         CROSS APPLY ( SELECT [Key]
                             ,Value
                       FROM OpenJson( (SELECT A.* For JSON Path,Without_Array_Wrapper,INCLUDE_NULL_VALUES)) 
                     ) AS B
      ) AS A
GROUP BY rowid,[key]
HAVING MAX(CASE WHEN Src=1 THEN Value END)
     <> MAX(CASE WHEN Src=2 THEN Value END)
ORDER BY rowid,[key];

输出

+-------+-----------+-----------+-----------+
| rowid |  column   | Org_Value | New_Value |
+-------+-----------+-----------+-----------+
|     2 | LastName  | ROBERRTO  | ROBERTO   |
|     2 | Phone     | 41324133  | 41324132  |
|     4 | Phone     | 56201550  | 56201551  |
|     5 | FirstName | ALFREDO   | ALFRIDO   |
|     5 | Phone     | 32356654  | 32356653  |
|     6 | LastName  | FERNANDO  | FERNANDOO |
+-------+-----------+-----------+-----------+