首页 > 解决方案 > SQL CHECKSUM_AGG(BINARY_CHECKSUM(*)) 为具有相似内容的 2 个不同表提供相同的结果

问题描述

我在 Microsoft SQL Server 中遇到了一些非常奇怪的东西,基本上它与CHECKSUM_AGG(BINARY_CHECKSUM(*))函数有关。

假设我有 2 个不同的表,内容如下:

如您所见,每个表只有 2 个可能的行内容:

但是,它们仍然不同,因为第二个表有 5 个这样的行组合,但是如果我尝试CHECKSUM_AGG(BINARY_CHECKSUM(*))通过运行来计算 2 个表中的

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) AS "Table 1 Checksum" FROM Table_1;
SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))AS "Table 2 Checksum" FROM Table_2;

它们将显示相同的结果:

2 个具有相同 CHECKSUM_AGG 结果的表

这很奇怪,我不知道为什么会这样。我正在执行该CHECKSUM_AGG功能以查看 2 个表是否具有相同的内容,到目前为止,它看起来运行良好。但是,在极少数情况下,两个表的内容与上面的两个表相似^^,恐怕该函数会为这两个表返回相同的结果。

有人可以解释一下这背后的原因,是否有任何方法可以缓解这个问题?

在此先感谢,我将非常感谢任何帮助:)

标签: sqlsql-serverchecksum

解决方案


BINARY_CHECKSUM正在检查值是否相同,但不考虑一个值与另一个表相比可能出现在一个表上的次数。如果值出现的次数很重要,并且您想检测到不一样,因为尽管它们具有相同的值,但一个表确实比另一个表具有更多的值,您可以使用它HASHBYTES来检测那里的差异。

BINARY_CHECKSUM 满足散列函数的属性:当应用于任何两个表达式列表时,如果两个列表的相应 > 元素具有相同的类型并且在使用等于 (=) 运算符比较时相等,则返回相同的值。

例子

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) AS "Table 1 Checksum",
HashBytes('md5',convert(varbinary(max),(SELECT * FROM Table_1 FOR XML AUTO))) AS "Table 1 Hashbytes",
 FROM Table_1;

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))AS "Table 2 Checksum",
HashBytes('md5',convert(varbinary(max),(SELECT * FROM Table_2  FOR XML AUTO))) AS "Table 2 Hashbytes",
FROM Table_2;

https://docs.microsoft.com/en-us/sql/t-sql/functions/binary-checksum-transact-sql?view=sql-server-ver15#remarks


推荐阅读