Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 需要系统定义的功能从两个表中选择更新的或不匹配的新记录_Sql_Sql Server_Tsql - Fatal编程技术网

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

Sql 需要系统定义的功能从两个表中选择更新的或不匹配的新记录,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个活动数据表,其中放置了旧值,在一个新表中,我将数据从该活动表移动到这个表中,如何查找插入或更新到新表中的更新或新记录,而不使用except、checksum(二进制校验和)和join,我正在寻找一个使用系统定义功能的解决方案。这个需求很有趣,因为最好的解决方案是使用,除了或完全连接。您试图做的是所谓的左反半联接。这是一个例子 请注意此示例数据和解决方案(请注意,不使用EXCEPT或join的我的解决方案是最后一个解决方案): 这是最新版本 select someid from (

我有一个活动数据表,其中放置了旧值,在一个新表中,我将数据从该活动表移动到这个表中,如何查找插入或更新到新表中的更新或新记录,而不使用except、checksum(二进制校验和)和join,我正在寻找一个使用系统定义功能的解决方案。

这个需求很有趣,因为最好的解决方案是使用
,除了
完全连接。您试图做的是所谓的
左反半联接
。这是一个例子

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

这是最新版本

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

请在此处显示您尝试过的代码。我还没有尝试过Yet。请更新您的问题:。请删除您的问题并添加一些代码以及基于该数据的预期输出。请您的问题-不要在comments.sql server management studio中发布代码或其他信息
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