比较具有相同模式的两个表以获得数据差异
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了比较具有相同模式的两个表以获得数据差异相关的知识,希望对你有一定的参考价值。
我正在研究一个典型的问题,我需要将两个表与完全相同的模式进行比较以获得数据差异。假设数据库为MS SQL或ORACLE。
更确切地说,这是我想要实现的目标:
- 我有一个ORG表和一些数据
- 我正在创建表ORG的副本作为BACKUP
- 现在我想更新表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
也适用于CLOB
s,所以(理论上)你可以连接列和行并计算整个表的哈希码。但这不是正确的方法,请记住文件的哈希码是通过组合线的哈希码来递增计算的。
下面是演示如何使用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()
该脚本启动哈希码,而不是遍历行和update
s哈希码,最后将其预设为字符串。这是处理文件时的典型方法,其中行的顺序很重要。在关系表中,未定义顺序。您认为该表与(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本机实现。
以上是关于比较具有相同模式的两个表以获得数据差异的主要内容,如果未能解决你的问题,请参考以下文章