Сравнение 2 таблиц для новых или обновленных строк с использованием составных ключей - PullRequest
1 голос
/ 11 ноября 2011

Я пишу tsql для SQL Server 2008. У меня есть две таблицы с примерно 2 миллионами строк в каждой. Исходная таблица обновляется ежедневно, а изменения помещаются в таблицу назначения на основе даты last_edit. Если эта дата новее в источнике, чем в месте назначения, обновите строку назначения. Если в источнике существует новая строка по сравнению с местом назначения, вставьте ее в место назначения. Это действительно только односторонний процесс, который меня интересует, от источника до места назначения. В исходной и целевой таблицах используется уникальный идентификатор из 4 столбцов: serialid, itemid, системный код и роль.

Моя таблица смоделирована аналогично приведенному ниже сценарию. Существует много столбцов данных, но в этом примере я ограничил их тремя. Я ищу 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 Ответ

1 голос
/ 11 ноября 2011

Несоответствующие строки могут быть найдены при левом / правом соединении и проверке ключей целевой таблицы на нулевое значение:

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