用于查找不匹配数据的SQL查询

时间:2016-08-15 14:24:06

标签: sql sql-server tsql

我有一个本地用户表,可以从我们的客户端获取数据。每周一次,他们将向我们提供其用户数据的更新版本。然后,我们需要将任何新用户提供给我们的用户表(这很简单),并使用任何新数据更新任何现有用户(这是我被困住的地方)。

因此,假设我们的本地表名为UserLocal,然后我们有一个表被删除并每周重写一次,来自客户端的新数据称为UserNew。带有一个用户样本的列如下所示:

UserLocal

UserId    UserCode    FirstName    LastName
12345     ABC         John         Doe

但是,来自客户端的新数据源如下所示:

UserNew

UserId    UserCode    FirstName    LastName
12345     XYZ         John         Doe

因此,John的UserCode已经改变了。我要做的是编写一个查询,查找UserNew中UserId与UserLocal中的行匹配但UserCode不匹配的所有行。

用这种语法很难。

3 个答案:

答案 0 :(得分:2)

基本理念是:

SELECT *
FROM UserNew n
    JOIN UserLocal l
        ON l.UserId = n.UserId
        AND l.UserCode != n.UserCode

答案 1 :(得分:1)

您需要使用MERGE命令。它用于根据需要更新或将记录插入表中。

互联网上有很多例子,可以找到命令的详细信息here

答案 2 :(得分:1)

如果您想在MERGE之前查看和/或跟踪更改

Declare @UserLocal table (UserId int,UserCode varchar(50),FirstName varchar(50),LastName varchar(50))
Insert Into @UserLocal values (12345,'ABC','John','Doe')

Declare @UserNew table (UserId int,UserCode varchar(50),FirstName varchar(50),LastName varchar(50))
Insert Into @UserNew values (12345,'XYZ','Johnnny','Doe')

Declare @XML xml
Set @XML = (Select * From (Select Ver=0,* from @UserLocal Union All Select Ver=1,* from @UserNew) A for XML RAW)
;with cteBase as (
    Select UserId       = r.value('@UserId','int') 
          ,Ver          = r.value('@Ver','int')
          ,Item         = Attr.value('local-name(.)','varchar(max)')
          ,Value        = Attr.value('.','varchar(max)')
    From @XML.nodes('/row') AS A(r)
    Cross Apply A.r.nodes('./@*[local-name(.)!="Ver"]') AS B(Attr)
)
,cteExt as (Select *,LastValue =Lag(Value) over (Partition By UserID,Item Order by Ver) From cteBase)
Select UserID
      ,Item
      ,Before=LastValue
      ,After =Value
 From  cteExt 
 Where Value<>LastValue and LastValue is not null
 Order By UserID,Item

返回

UserID  Item        Before  After
12345   FirstName   John    Johnnny
12345   UserCode    ABC     XYZ