如何找出SQL

时间:2017-12-30 04:33:39

标签: sql sql-server sql-server-2014

我有两个包含100列的表,我想知道这两个表中哪个列值发生了变化。我可以找到哪一行已更改,但我想要更改哪一列而不是整行。

Table 1 
          name   ID    Dept   Email       EmpID    Salary  Gender  
          Rob     1     IT     I@i.com     100    5000       M 
          Mary    2     HR     M@m.com     20      6000      F 
          Jack    3     IT     J@j.com     30       7000     M 
          Harry   4     Fin     h@h.com    50       5000     M 
          Jay     5     Eng     Null        60       5000    M  
          Ken     6     HR      K@K.com     70       Null    M  

 Table 2 
          name   ID    Dept   Email       EmpID   Salary  Gender  
          Rob     1     IT     I@i.com     100    5000       M 
          Mary    2     HR     M@m.com     20      6000      F 
          Jack    3     IT     J@j.com     150     7000     M 
          Harry   4     Fin     h@h.com    50       Null    M 
          Jay     5     Eng     Jy@jy.com  60       5000     M  
          Ken     6     HR      K@K.com    70       6000     M  

正如我们可以看到Jay for Jay已经存在,Jack的Emp ID已经改变,Harry的Salary在表2中为空,而Ken为Salary添加了Salary。

预期输出(如果这是可能的,因为我不想看到所有行值,我只想查看哪个列值已更改,因为ID是唯一标识符,我想知道哪个ID列值发生了变化)

 ID     columnvaluechanged
  3        EmpID 
  4        Salary 
  5        Email 
  6        Salary 

1 个答案:

答案 0 :(得分:2)

这是使用unpivot技术的一种方法

;WITH tab1
     AS (SELECT id,
                colName,
                value
         FROM   Yourtable1
                CROSS apply (VALUES (NAME,'name'),(Dept,'Dept'),(Email,'Email'),
                                    (Cast(EmpID AS VARCHAR(50)),'EmpID'),
                                    (Cast(Salary AS VARCHAR(50)),'Salary'),
                                    (Gender,'Gender')) cs (value, colName)),
     tab2
     AS (SELECT id,
                colName,
                value
         FROM   Yourtable2
                CROSS apply (VALUES (NAME,'name'),(Dept,'Dept'),(Email,'Email'),
                                    (Cast(EmpID AS VARCHAR(50)),'EmpID'),
                                    (Cast(Salary AS VARCHAR(50)),'Salary'),
                                    (Gender,'Gender')) cs (value, colName))
SELECT t1.ID,
       t1.colName,
       t1.value AS tab1_value,
       t2.value AS tab2_value
FROM   tab1 t1
       INNER JOIN tab2 t2
               ON t1.ID = t2.ID
                  AND t1.colName = t2.colName
                  AND Isnull(t1.value, '') <> Isnull(t2.value, '')