我正在将来自不同服务器上不同数据库的一堆表与主记录进行比较。我需要知道由 标识的哪些服务器locationID
具有不匹配的行,因为它们可能需要维护。
我有一个简单的EXCEPT
查询,我比较了一个表,其中每一行都是来自每个服务器的配置;table1
每台服务器有一行,所有配置加上locationID
这是一个告诉我它是哪台服务器的列。我将所有这些与table1_master
具有正确设置的表进行比较,但我排除了它,locationID
因为它不匹配。
下面的简单查询:
SELECT everything, but, locationID
FROM table1
EXCEPT
SELECT everything, but, locationID
FROM table1_master
我比较所有服务器时只有一个主行,我没有locationID
在这里选择它。
这是我正在比较的行的一个示例。每个都有一个主键、一个列varchar
和一个包含数十个列的巨大列表。我想比较除LocationID 之外的所有列,但我需要 LocationID 来识别行。
LocationID setting setting setting setting
CS02 C Y Y Y Y
CS03 C Y Y Y Y
CS06 C Y N Y Y
在此示例中,CS02 是我的主记录,因此由于 CS02 和 CS03 中的所有设置都相同,因此这些行不会显示,但 CS06 会显示。但在我的EXCEPT
查询中,我实际上并没有捕获 LocationID,所以我实际上并不知道返回了哪一行。
这会返回我需要的行,但不是locationID
,所以我不知道哪些行是错误的。有什么方法可以locationID
在踢出匹配行的同时包含在结果集中?
我想到的解决方案是为table1_master
表中的每个服务器创建一行,因此每个都locationID
被表示,但除此之外它们都具有相同的数据。然后我的EXCLUDE
查询应该返回locationID
和我的信息,但这是最好的方法吗?
您也可以使用动态 SQL 来执行此操作,而无需手动构建所有列名。
您可以按原样获取此查询的输出并将查询存储在某处,或者您可以注释掉
SELECT
并取消注释EXEC
并将其保留为永久动态 SQL - 在这种情况下,它将自动适应两个表中的列更改。另一个想法(假设 LocationID 是唯一的) - 我突然想到您可能想要包含主行,以便您可以快速发现不同的列:
这个版本稍微便宜一些(主要是通过避免
DISTINCT
与主表对抗,代价是需要再次指定所有列 - 您可以再次按照上面的方式自动化):然而,所有这些选项的性能都比 Rachel 的 simple 更差,而且计划更差
LEFT JOIN
。我试图坚持使用的主题,EXCEPT
即使它更多地是关于语法而不是性能。关键要点是,如果列数太多而无法手动处理,您可以使用上面的动态 SQL 方法来构造您想要使用的任何查询 - 您可以执行一次并存储结果,或者拥有代码每次生成。要使用动态 SQL 生成 Rachel 的查询,不需要太多更改:
我会推荐:
Hash
作为持久计算列的字段,其定义如下:HASHBYTES('SHA1', Field1 + Field2 + Field3...)
HASH
将“主”中的值与其他记录进行比较就像是
仅在每列上加入两个表(或使用 where 语句)并选择第二个表中不存在的项目有什么问题?
它可能不漂亮,但它应该工作