sql - 比较两个表并找出列值的差异

标签 sql sql-server t-sql

我想比较两个表(相同的列)并找出哪些列值发生了变化。

这是一个包含示例数据的示例。

employee_original 表有 6 列。

CREATE TABLE [dbo].[employee_original](
    [emp_id] [int] IDENTITY(1,1) NOT NULL,
    [first_name] [varchar](100) NOT NULL,
    [last_name] [varchar](100) NOT NULL,
    [salary] int NOT NULL,
    [city] [varchar](20) NOT NULL,
    [department] [varchar](20) NOT NULL,
PRIMARY KEY CLUSTERED 
(
    [emp_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO

INSERT INTO employee_original VALUES ( 'Julia', 'Schultz', 100, 'New York', 'Tech');
INSERT INTO employee_original VALUES ( 'Vincent', 'Trantow', 200, 'Moscow', 'HR');
INSERT INTO employee_original VALUES ( 'Whitney ', 'Pouros', 500, 'Miami', 'Accounting');
INSERT INTO employee_original VALUES ( 'Chandler', 'Osinski', 10, 'Singapore', 'Purchasing');
INSERT INTO employee_original VALUES ( 'Sydnie', 'Green', 700, 'Ireland', 'Operations');
INSERT INTO employee_original VALUES ( 'Josefa', 'Anderson', 800, 'Berlin', 'Purchase');
INSERT INTO employee_original VALUES ( 'Brayan', 'Bergstrom', 900, 'New York', 'Operations');
INSERT INTO employee_original VALUES ( 'Shyanne', 'Kris', 900, 'New York', 'Sales');

employee_modified 具有相同的员工,但少数员工的某些属性已更改。

CREATE TABLE [dbo].[employee_modified](
    [emp_id] [int] IDENTITY(1,1) NOT NULL,
    [first_name] [varchar](100) NOT NULL,
    [last_name] [varchar](100) NOT NULL,
    [salary] int NOT NULL,
    [city] [varchar](20) NOT NULL,
    [department] [varchar](20) NOT NULL,
PRIMARY KEY CLUSTERED 
(
    [emp_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO

INSERT INTO employee_modified VALUES ( 'Julia', 'Schultz', 100, 'New York', 'Tech');
INSERT INTO employee_modified VALUES ( 'Vincent', 'Wyman', 500, 'Moscow', 'HR');
INSERT INTO employee_modified VALUES ( 'Whitney ', 'Pouros', 500, 'Miami', 'Sales');
INSERT INTO employee_modified VALUES ( 'Chandler', 'Osinski', 10, 'Singapore', 'Purchasing');
INSERT INTO employee_modified VALUES ( 'Sydnie', ' Cartwright', 900, 'Ireland', 'Operations');
INSERT INTO employee_modified VALUES ( 'Joseph', 'Anderson', 800, 'Berlin', 'Purchase');
INSERT INTO employee_modified VALUES ( 'Bryan', 'Bergstrom', 900, 'Naples', 'Operations');
INSERT INTO employee_modified VALUES ( 'Shyanne', 'Jakubowski', 900, 'New York', 'Accounting');

我正在寻找一个结果,可以告诉我哪个员工的哪个字段发生了变化。 例如emp_id =2 姓氏和工资发生变化。所以输出应该如下所示:

emp_id  attribute   orignial_value  new_value
2       last_name   Trantow         Wyman
2       salary      200             500

这是我迄今为止尝试过的:

(1) 连接表并查找发生变化的内容:

DROP TABLE IF EXISTS #temp;

SELECT      distinct 
            o.emp_id,
            o.first_name [original_first_name], m.first_name [modified_first_name],
            o.last_name [original_last_name], m.last_name [modified_last_name],
            o.salary [original_salary], m.salary [modified_salary],
            o.city [original_city], m.city [modified_city],
            o.department [original_department], m.department [modified_department]
            into #temp from  
            [dbo].[employee_original] o inner join [dbo].[employee_modified] m on o.emp_id = m.emp_id

select * from #temp

给我

enter image description here

(2) 与#temp自连接并找出哪些属性发生了变化。

-- All Last Name Changes. 
select distinct t1.emp_id, t1.original_last_name, t2.modified_last_name
        from #temp t1
            inner join #temp t2 on t1.emp_id = t2.emp_id
        where t1.original_last_name <> t2.modified_last_name

-- All Department changes
select distinct t1.emp_id, t1.original_department, t2.modified_department
        from #temp t1
            inner join #temp t2 on t1.emp_id = t2.emp_id
        where t1.original_department <> t2.modified_department

关于如何达到我想要的结果的任何指示。

最佳答案

这里有一个选项,可以动态取消数据透视,而无需实际使用动态 SQL。

示例

Select emp_id
      ,[key]
      ,Org_Value = max( case when Src=1 then Value end)
      ,New_Value = max( case when Src=2 then Value end)
 From (
        Select Src=1
              ,emp_id 
              ,B.*
         From [employee_original] A
         Cross Apply ( Select [Key]
                             ,Value
                       From OpenJson( (Select A.* For JSON Path,Without_Array_Wrapper,INCLUDE_NULL_VALUES  ) ) 
                     )  B
        Union All
        Select Src=2
              ,emp_id 
              ,B.*
         From [employee_modified] A
         Cross Apply ( Select [Key]
                             ,Value
                       From OpenJson( (Select A.* For JSON Path,Without_Array_Wrapper,INCLUDE_NULL_VALUES  ) ) 
                     )  B
      ) A
 Group By emp_id,[key]
 Having max( case when Src=1 then Value end)
     <> max( case when Src=2 then Value end)
 Order By emp_id,[key]

结果

enter image description here

关于sql - 比较两个表并找出列值的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69995569/

相关文章:

c# - 为什么我无法通过 C# 应用程序连接到远程 SQL 服务器?

mysql - 从旧的中删除数量并添加到新的中

php - 组合多个 MySQL JOIN 查询

sql - 在存储过程中选择多个 XML 元素

SQL Server - 对整个列求和并分组

t-sql - 获取一个链接服务器属性

sql - 过滤并保留最近的重复项

sql-server - 计算 SQL Server 中行中重复值的数量

Mysql如何连接2个子查询

sql - 基于sql中的空/非空参数构建where子句