在 MS Access 或 SQL Server 中查找 2 个表之间的差异

Posted

技术标签:

【中文标题】在 MS Access 或 SQL Server 中查找 2 个表之间的差异【英文标题】:Finding difference between 2 tables in MS Access or SQL Server 【发布时间】:2012-06-29 13:31:07 【问题描述】:

我有 2 个 Excel 文件作为两个表格导入 MS Access。这两个表相同,但在不同日期导入。

现在,我怎样才能知道以后更新了哪些行和哪些字段?任何帮助将不胜感激。

【问题讨论】:

你能提供这些表的架构吗? 假设他们有一个共同的“ID”字段,在该字段上加入他们,并在 UpdatedDate 不同的地方添加一个 WHERE 子句。 或者,如果您没有 UpdatedDate 类型的字段,那么您必须一一比较所有字段。如果您甚至没有 ID(或任何其他唯一的,如代码、EAN 等)字段,那么您首先需要写下您需要比较的内容和方式 - 之后选择将很容易编写:)跨度> @Arvo 我没有表的任何唯一标识符。那么,我可以举个例子吗? 我说 - 写下您需要比较的 [字段或字段组合] 以及 [您认为相等的内容、不相等的内容以及使您的表格行独一无二的内容] 的方式。你不能做你不了解的事情,是吗? 【参考方案1】:

查找插入的记录很容易

select * from B where not exists (select 1 from A where A.pk=B.pk)

查找已删除的记录同样简单

select * from A where not exists (select 1 from B where A.pk=B.pk)

查找更新的记录很痛苦。以下严格查询假设您有可为空的列,并且它应该适用于所有情况。

select B.*
  from B
  inner join A on B.pk=A.pk
 where A.col1<>B.col1 or (IsNull(A.col1) and not IsNull(B.col1)) or (not IsNull(A.col1) and  IsNull(B.col1))
    or A.col2<>B.col2 or (IsNull(A.col2) and not IsNull(B.col2)) or (not IsNull(A.col2) and  IsNull(B.col2))
    or A.col3<>B.col3 or (IsNull(A.col3) and not IsNull(B.col3)) or (not IsNull(A.col3) and  IsNull(B.col3))
    etc...

如果列定义为 NOT NULL,那么查询就简单多了,只需删除所有 NULL 测试。

如果列可以为空,但您可以确定一个永远不会出现在数据中的值,则使用简单的比较,例如:

Nz(A.col1,neverAppearingValue)<>Nz(B.col1,neverAppearingValue)

【讨论】:

我没有任何表的主键,能否请您给我一个相同的示例? 您可能没有为您的表定义 PK,但希望您在某处有一个逻辑键。它可能是一个多部分键,在这种情况下当然需要扩展 join ON 子句。【参考方案2】:

我相信这应该像运行这样的查询一样简单:

SELECT * 
FROM Table1
    JOIN Table2
         ON Table1.ID = Table2.ID AND Table1.Date != Table2.Date

【讨论】:

【参考方案3】:

执行此操作的一种方法是取消透视两个表,因此您会得到一个带有 , , 的新表。但请注意,您必须考虑类型。

例如,以下获取字段的差异:

with oldt as (select id, col, val
              from <old table> t
              unpivot (val for col in (<column list>)) unpvt
             ),
     newt as (select id, col, val
              from <new table> t
              unpivot (val for col in (<column list>)) unpvit
             )
select *
from oldt full outer join newt on oldt.id = newt.id
where oldt.id is null or newt.id is null

连接的替代方法相当麻烦。此版本显示是否添加、删除列以及更改了哪些列(如果有):

select *
from (select coalesce(oldt.id, newt.id) as id,
             (case when oldt.id is null and newt.id is not null then 'ADDED'
                   when oldt.id is not null and newt.id is null then 'DELETED'
                   else 'SAME'
              end) as stat,
             (case when oldt.col1 <> newt.col1 or oldt.col1 is null and newt.col1 is null
                   then 1 else 0 end) as diff_col1,
             (case when oldt.col2 <> newt.col2 or oldt.col2 is null and newt.col2 is null
                   then 1 else 0 end) as diff_col2,
             ...
      from <old table> oldt full outer join <new table> newt on oldt.id = newt.id
     ) c
where status in ('ADDED', 'DELETED') or
     (diff_col1 + diff_col2 + ... ) > 0

它确实具有适用于任何数据类型的优势。

【讨论】:

【参考方案4】:
(Select * from OldTable Except Select *from NewTable)
Union All
(Select * from NewTable Except Select *from OldTable)

【讨论】:

以上是关于在 MS Access 或 SQL Server 中查找 2 个表之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

在 MS Access 或 SQL Server 中查找 2 个表之间的差异

MS SQL Server / Access 的在线表格编辑器?

在将 MS Access 拆分为 SQL Server 以执行查询后使用哪个引擎

如何从 SQL Server 读取 MS Access 数据库以更新一个或多个表列中的数据?

更新 SQL Server 数据库时如何更新 MS Access 表单?

SQL Server 后端缺少 MS Access 数据库复选框列表筛选器