使用复合键比较2个表以获取新行或更新行

时间:2011-11-11 10:37:16

标签: tsql join composite-key

我正在为SQL Server 2008编写tsql。我有两个表,每个表大约有200万行。 Source表每天更新,并根据last_edit日期将更改推送到Destination表。如果此日期在源中比目标更新,则更新目标行。如果源中存在新行与目标相比将其插入目标。这实际上只是我关注的一个单向过程,从源到目的地。源表和目标表在4列(serialid,itemid,systemcode和role)中使用唯一标识符。

我的表格类似于下面的脚本。有许多数据列,但在本例中我将其限制为3。我正在寻找2个输出。包含要更新的行的1组数据和包含要添加的行的1组数据。

CREATE TABLE [dbo].[TABLE_DEST](
  [SERIALID] [nvarchar](20) NOT NULL,
  [ITEMID] [nvarchar](20) NOT NULL,
  [SYSTEMCODE] [nvarchar](20) NOT NULL,
  [ROLE] [nvarchar](10) NOT NULL,
  [LAST_EDIT] [datetime] NOT NULL],
  [DATA_COLUMN_1] [nvarchar](10) NOT NULL,
  [DATA_COLUMN_2] [nvarchar](10) NOT NULL,
  [DATA_COLUMN_3] [nvarchar](10) NOT NULL
)

CREATE TABLE [dbo].[TABLE_SOURCE](
 [SERIALID] [nvarchar](20) NOT NULL,
 [ITEMID] [nvarchar](20) NOT NULL,
 [SYSTEMCODE] [nvarchar](20) NOT NULL,
 [ROLE] [nvarchar](10) NOT NULL,
 [LAST_EDIT] [datetime] NOT NULL],
 [DATA_COLUMN_1] [nvarchar](10) NOT NULL,
 [DATA_COLUMN_2] [nvarchar](10) NOT NULL,
 [DATA_COLUMN_3] [nvarchar](10) NOT NULL
)

以下是我对更新数据集的了解。

select s.*
from table_dest (nolock) inner join table_source s (nolock) 
  on s.SYSTEMCODE = fd.SYSTEMCODE1Y
    and s.ROLE = d.ROLE
    and s.SERIALID = d.SERIALID
    and s.ITEMID = d.ITEMID
    and s.LAST_EDIT > d.LAST_EDIT

我不知道如何最好地找到要添加的行。但是解决方案必须对数据库非常有效。

1 个答案:

答案 0 :(得分:1)

可以使用左/右连接找到不匹配的行,并检查目标表键是否为null:

select s.*, case when d.key1 is null then 'insert' else 'update' end [action]
from [table_dest] d right join [table_source] s on (d.key1 = s.key1 /* etc.. */)

如果您只是为了执行相应的操作而需要这些行,那么您可以使用以下功能:

merge [table_dest] d
using [table_source] s on (d.key1 = s.key1 /* etc.. */)
when mathed then
   update set d.a = s.a
when not matched by target then
   insert (key1, .., a) values (s.key1, ..., s.a);