比较具有相同模式的两个表以获得数据差异

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了比较具有相同模式的两个表以获得数据差异相关的知识,希望对你有一定的参考价值。

我正在研究一个典型的问题,我需要将两个表与完全相同的模式进行比较以获得数据差异。假设数据库为MS SQL或ORACLE。

更确切地说,这是我想要实现的目标:

  1. 我有一个ORG表和一些数据
  2. 我正在创建表ORG的副本作为BACKUP
  3. 现在我想更新表ORG的某些SPECIFIC行中的一些SPECIFIC列。

什么是找到表BACKUP和ORG之间差异的最简单有效的方法?

我看到很少的选择,如使用UNIONS,PIVOT,UNPIVOT等。但我很困惑,需要一些指导,以便采取最佳方式。

谢谢,

答案

您可以使用SET运算符MINUS/INTERSECT,具体取决于您想要的,两个表中行之间的差异或匹配。

要获得差异,请使用MINUS:

SELECT <here_goes_your_column_list> FROM org
MINUS
SELECT <here_goes_your_column_list> FROM backup

要获得比赛,请使用INTERSECT:

SELECT <here_goes_your_column_list> FROM org
INTERSECT
SELECT <here_goes_your_column_list> FROM backup

documentation中查看更多详细信息。

另一答案

试试这个

-- compare tables data and data2
with data as
 (select 1 as id, 'A' as val
    from dual
  union
  select 2, 'B' from dual),
data2 as
 (select 1 as id, 'A' as val
    from dual
  union
  select 2, 'BC' from dual)

 -- data not in data2 and data2 not in data:
 (select *
    from data2
  minus
  select * from data) union all
 (select *
    from data
  minus
  select * from data2);
另一答案

如果问题是要检查两个表的身份,即答案是yes - 表包含相同的数据或no - 存在差异,还有另一种方法,在关系数据库中不常见,但状态为文件的艺术。

这与使用哈希码检查下载文件的“正确性”(即与原始身份相同)的方法相同。如果你看到相同的哈希码,答案是yes你有正确的文件。

如何将这种方法转换为关系数据库?

Oracle提供了standard_hash函数,用于计算字符串的MD5哈希码

 select standard_hash('foo bar', 'MD5') hash_code from dual; 

 HASH_CODE                      
 --------------------------------
 327B6F07435811239BC47E1544353273 

所以你可以比较列值。函数standard_hash也适用于CLOBs,所以(理论上)你可以连接列和行并计算整个表的哈希码。但这不是正确的方法,请记住文件的哈希码是通过组合线的哈希码来递增计算的。

下面是演示如何使用Java类MD5计算java.security.MessageDigest哈希码我正在使用Groovy脚本,因为遗憾的是这在PL / SQL中是不可能的。

 MessageDigest digest = MessageDigest.getInstance("MD5") 
 byte[] md5hash 

 groovyCon.eachRow ('select txt from MY_TABLE order by id') 
    {
       digest.update(it.txt.getBytes(StandardCharsets.UTF_8))
    }   

 md5hash = digest.digest();
 println md5hash.encodeHex().toString()

该脚本启动哈希码,而不是遍历行和updates哈希码,最后将其预设为字符串。这是处理文件时的典型方法,其中行的顺序很重要。在关系表中,未定义顺序。您认为该表与(A,B,C)和(C,B,A)相同。

请参阅here讨论如何使用XOR将哈希码组合在一个顺序无关的事物中。

这是组合两个字符串的哈希码的示例

 select UTL_RAW.BIT_XOR(standard_hash('foo', 'MD5'), standard_hash('bar', 'MD5')) hash_code from dual;

 HASH_CODE                      
 --------------------------------
 9B0805C206B7EBB8B6B9931D83E9F52A 

这种方法具有很大的优势,可以使用PL / SQL实现。请参阅此处PL / SQL aggregate function MD5_XOR实现计算整个表的MD5哈希码的示例。

 select   MD5_XOR(txt) hash_code, count(*) cnt 
 from MY_TABLE;

 HASH_CODE                          CNT
 --------------------------------   -------
 173F1F8F85F1A154044B7629A23E949C   102 

当然,您可以连接参数以计算整个表的哈希码

 select MD5_XOR(to_char(id)||COL_TXT|| to_char(COL_DATE,'dd.mm.yyyy hh24:mi:ss')) md5  from  MY_TABLE;

或者你可以使用GROUP BY表格的一部分,看看哪些组是相同的,哪些是不同的。

更好的是,如果这个聚合函数将由Oracle本地实现,那么性能将会更好,并且使用基于set操作的SQL比较(需要对表进行排序)要好得多。 XOR组合不需要排序并具有O(N)复杂性,但用户实现受上下文切换的影响。

请参阅here,以使其成为Oracle本机实现。

以上是关于比较具有相同模式的两个表以获得数据差异的主要内容,如果未能解决你的问题,请参考以下文章

使用两个不同的外键连接两个表以获得相同的字段

具有不同表结构的两个DB2表中的数据值之间的差异

在 R 中比较和连接数据框

从一个列值上的两个比较列 sum() 聚合返回一个 SQL 表

比较 2 个表中的值并生成具有差异的新表

具有不同表结构的两个 DB2 表中的数据值之间的差异