我有一个本地用户表,可以从我们的客户端获取数据。每周一次,他们将向我们提供其用户数据的更新版本。然后,我们需要将任何新用户提供给我们的用户表(这很简单),并使用任何新数据更新任何现有用户(这是我被困住的地方)。
因此,假设我们的本地表名为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不匹配的所有行。
用这种语法很难。
答案 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