SQL Server 中是不是有一种方法可以显示两个具有相同布局并共享一些公共数据的表之间的字段差异

Posted

技术标签:

【中文标题】SQL Server 中是不是有一种方法可以显示两个具有相同布局并共享一些公共数据的表之间的字段差异【英文标题】:Is there a way in SQL Server to show the differences in fields between two tables that have an identical layout and share some common dataSQL Server 中是否有一种方法可以显示两个具有相同布局并共享一些公共数据的表之间的字段差异 【发布时间】:2019-07-28 04:03:06 【问题描述】:

我在两个数据库(两个不同的组织)上有两个表,它们具有相同的布局 - 它们是物料主表。一个列出了大约 600k 材料,一个列出了大约 100k - 它们共享大约 35k 相同的材料。问题是一个组织可能具有与另一个组织不同的属性,即一个组织的价格可能不同,或者一个组织与另一个组织的季节可能不同。如果可能的话,我试图找到一种方法来并排展示,一个组织中的材料与另一个组织中的材料之间存在差异。到目前为止,我只提出了下面的代码 - 它正在使用 EXCEPT 但似乎它只能从一行或另一行返回数据,而我试图同时查看两者。有什么想法吗?

我已经尝试过使用 EXCEPT 语句,但只得到了结果的一侧。

select * from pdx_sap_user..vw_mm_material 
where material in (select material

from pdx_sap_user..vw_mm_material 

where material  in (select material from usts_user..vw_mm_material)) -- used to get to the shared materials

EXCEPT 

select * from usts_user..vw_mm_material

我想获得共享的 35k 材料,并能够展示它们的不同之处。作为参考,这些表中有大约 300 列,因此列出每一列可能有点麻烦。

样本数据:

【问题讨论】:

我已经编辑以提供一个小样本数据 - 请注意,“组织”字段实际上不在表格中 - 它们在列方面是相同的。 它们之间是否有共同的密钥? 11040的材料在各个组织之间是否完全一样? 是的,我很抱歉 - 材料是唯一的关键 【参考方案1】:

您可以从每个组织表中选择常用材料,并添加一个组织伪列。然后只需将这两个查询合并在一起并对它们进行排序,使行一个接一个地排列。

DECLARE @og1Mats TABLE (
    Material INT, Description NVARCHAR(50), Color NVARCHAR(50), MSRP INT
)

DECLARE @og2Mats TABLE (
    Material INT, Description NVARCHAR(50), Color NVARCHAR(50), MSRP INT
)

INSERT INTO @og1Mats VALUES (11040, 'World Cup', 'black', 100),(11050, 'Fabric', 'yellow', 10),(11060, 'Steel', 'gray', 50);
INSERT INTO @og2Mats VALUES (11040, 'World Cup', 'black', 120),(11030, 'Concrete', 'gray', 10),(11060, 'Steel', 'black', 55);

WITH common AS (
    SELECT o1.Material FROM @og1Mats o1
    INNER JOIN @og2Mats o2 ON o1.Material=o2.Material
)
SELECT o1.*, 1 as organization
FROM @og1Mats o1
INNER JOIN common c ON c.Material=o1.Material
UNION ALL 
SELECT o2.*, 2 as organization
FROM @og2Mats o2 
INNER JOIN common c ON c.Material=o2.Material
ORDER BY
    Material
    , organization

这将为您提供类似于示例数据的输出,其中行按材料和组织分组。然后,您可以使用它手动或使用其他工具来比较数据。

【讨论】:

我喜欢这种方法——我认为它也是 SQL 可以提供的最好的方法——表有 300 列,因此手动缩小范围会很痛苦。我正在学习 R 并在那里寻找一些可能的解决方案。感谢您提供周到的反馈。 @XCCH004,在上面的脚本中说如果11040 在两个组织中是 100% 相同的,那么它也会在结果集中返回。这是你的要求吗?那么上面的示例数据的结果集中应该是什么?【参考方案2】:
DECLARE @og1Mats TABLE (
Material INT, Description NVARCHAR(50), Color NVARCHAR(50), MSRP INT
)

DECLARE @og2Mats TABLE (
Material INT, Description NVARCHAR(50), Color NVARCHAR(50), MSRP INT
)

INSERT INTO @og1Mats VALUES (11040, 'World Cup', 'black', 100)
,(11050, 'Fabric', 'yellow', 10),(11060, 'Steel', 'gray', 50);

INSERT INTO @og2Mats VALUES (11040, 'World Cup', 'black', 120)
,(11030, 'Concrete', 'gray', 10),(11060, 'Steel', 'black', 55);

;with CTE as
(
select * from @og1Mats
except
select * from @og2Mats
),
CTE1 as
(
select * from @og2Mats
except
select * from @og1Mats
)

select * from
(
select * from CTE
union all
select * from CTE1
)t4
order by Material

无论如何都应该避免使用select *

【讨论】:

以上是关于SQL Server 中是不是有一种方法可以显示两个具有相同布局并共享一些公共数据的表之间的字段差异的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 查询上次移动的项目

sql server 和统计配置文件

如何在 SQL Server 中解析 json 格式的字符串

在 SQL Server 表中搜索值列表的最有效方法

如何避免两次编写 SQL Server 查询以避免重复?

SQL Server FileStream (转载)