需要系统定义的功能,以从两个表中选择更新或不匹配的新记录

问题描述 投票:-3回答:1

我有一个实时数据表,其中放置旧值,在新表中我将数据从该实时表移动到此表如何查找在新表中插入或更新的更新或新记录,而不使用,校验和(binary_checksum)和join,我正在寻找使用系统定义函数的解决方案。

sql sql-server tsql
1个回答
0
投票

这个要求很有意思,因为最好的解决方案是使用EXCEPTFULL JOIN。你想要做的是所谓的left anti semi join。这是一个good article about the topic

请注意此示例数据和解决方案(请注意,我的解决方案不使用EXCEPT或连接是最后一个解决方案):

-- sample data 
if object_id('tempdb.dbo.orig') is not null drop table dbo.orig;
if object_id('tempdb.dbo.new')  is not null drop table dbo.new;
create table dbo.orig (someid int, col1 int, constraint uq_cl_orig unique (someid, col1));
create table dbo.new  (someid int, col1 int, constraint uq_cl_new unique (someid, col1));

insert dbo.orig values (1,100),(2,110),(3,120),(4,2000)
insert dbo.new  values (1,100),(2,110),(3,122),(5,999);

这是EXCEPT版本

select someid 
from
(
  select * from dbo.new except
  select * from dbo.orig
) n
union -- union "distict" 
select someid
from
(
  select * from dbo.orig except 
  select * from dbo.new
) o;

这是一个全连接解决方​​案,它还会告诉您记录是否被删除,更改或添加:

select
  someid   = isnull(n.someid, o.someid), 
  [status] =
    case 
      when count(isnull(n.someid, o.someid)) > 1 then 'changed'
      when max(n.col1) is null then 'removed' else 'added'
    end
from dbo.new n
full join dbo.orig o 
  on n.col1=o.col1 and n.someid = o.someid
where n.col1 is null or o.col1 is null
group by isnull(n.someid, o.someid);

但是,因为那些有效的解决方案不是一个选项 - 你需要使用NOT IN或NOT EXISTS子查询....并且因为它必须是一个函数,我将逻辑封装到一个函数中。

create function dbo.newOrChangedOrRemoved()
returns table as return

-- get the new records
select someid, [status] = 'new'
from dbo.new n
where n.someid not in (select someid from dbo.orig)
union all
-- get the removed records
select someid, 'removed'
from dbo.orig o
where o.someid not in (select someid from dbo.new)
union all
-- get the changed records
select someid, 'changed' 
from dbo.orig o
where exists
(
  select *
  from dbo.new n
  where o.someid = n.someid and o.col1 <> n.col1
);

结果:

someid      status
----------- -------
5           new
4           removed
3           changed
© www.soinside.com 2019 - 2024. All rights reserved.