使用组合键比较 2 个表中的新行或更新行

发布于 2024-12-14 14:58:27 字数 1323 浏览 2 评论 0原文

我正在为 SQL Server 2008 编写 tsql。我有两个表,每个表大约有 200 万行。源表每天都会更新,更改会根据上次编辑日期推送到目标表。如果源中的该日期比目标中的日期新,则更新目标行。如果与目标相比,源中存在新行,则将其插入目标中。这实际上只是我关心的从源头到目的地的单向过程。源表和目标表使用跨 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

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

I'm writing tsql for SQL Server 2008. I've got two tables with roughly 2 million rows each. The Source table gets updated daily and changes are pushed to the Destination table based on a last_edit date. If this date is newer in source than destination then update the destination row. If a new row exists in source compared to destination insert it into destination. This is really only a one way process that I'm concerned with, from source to destination. The source and destination table use a unique identifier across 4 columns, serialid, itemid, systemcode, and role.

My table are modeled similar to the script below. There are many data columns but I've limited it to 3 in this example. I'm looking for 2 outputs. 1 set of data with rows to update and 1 set of data with rows to add.

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
)

Here's what I've got for the update dataset.

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

I don't know how best to accomplish finding the rows to add. But the solution has to be pretty efficient for the database.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

汐鸠 2024-12-21 14:58:27

可以通过左/右连接并检查目标表键是否为空来找到不匹配的行:

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);

Unmatched rows can be found with left/right join and checking target table keys for 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.. */)

If you need these rows just to perform respective operations then there is special feature for you:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文