2016-08-15 263 views
0

我有一个本地用户表,它从我们的客户端获取数据。每周一次,他们会向我们提供其用户数据的更新版本。然后,我们需要将任何新用户添加到我们的用户表中(这很简单),并用任何新数据更新任何现有用户(这是我卡住的地方)。查询不匹配数据的SQL查询

因此,假设我们的本地表名为UserLocal,然后我们有一张表,每周用一个名为UserNew的客户端的新数据擦除并重写一次。列,与一个用户的样本,看起来是这样的:

UserLocal 

UserId UserCode FirstName LastName 
12345  ABC   John   Doe 

但是,从客户端的新数据馈送是这样的:

UserNew 

UserId UserCode FirstName LastName 
12345  XYZ   John   Doe 

所以,约翰的用户代码已经改变。我想要做的是编写一个查询,查找UserNew中UserId与UserLocal中的行相匹配的所有行,但UserCode不匹配。

用这种语法很难。

+0

两个表中的'UserId'主键?请显示DDL。 – Serg

+0

它没有设置为主键,但值是唯一的 –

+0

您在上面的查询中有sn.Student_ID_Number = sn.Student_ID_Number - 因此多行:-)是否应该是sn.Student_ID_Number = s.Student_ID_Number? – bhs

回答

2

的基本思路是:

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

是的,这是我第一次尝试。它没有完成工作。它运行30秒以上并返回数千个重复的行。似乎合乎逻辑但不起作用 –

+0

您确定每个表中的每个用户只有一条记录吗? –

+0

我刚查过。是。两个表中每个用户的唯一行数。 –

1

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

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

+0

好的,谢谢BHS。我将最终到达合并数据的地方。现在我只需要看看有多少行将被合并,以及它们是哪些行。 –

+0

合并很容易写 - OUTPUT子句也可以给你插入和更新的细节 – bhs

+0

好吧,我会看看这个。谢谢 –

0

您可以使用合并或三个DML语句..

Insert into localtable 
     select * from clienttable ct 
     where not exists(select 1 from localtable t where t.userid=ct.userid) 

--delete..not exists also can be used 

delete lc 
from 
localtable lc 
join 
clinettable ct 
on ct.userid<>lc.userid 


---update 

;With cte 
as 
(
select * from clienttable 
except 
select * from localtbale 
) 
update lc 
set lc.usercode=c.usercode 
--do for all columns 
set 
from 
localtable lc 
join cte c 
on c.userid=lc.userid 
1

如果你想看到和/或跟踪更改合并

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 

返回

之前