SQL Server:将两个表与UNION和Select * plus其他标签列进行比较

时间:2014-08-27 16:59:38

标签: sql sql-server union intersect

我一直在使用Jeff' Server blog上的示例来比较两个表来找出差异。

在我的情况下,表是备份和当前数据。我可以通过这个SQL语句获得我想要的东西(通过删除大多数列来简化)。然后,我可以看到每个表格中的行没有完全匹配,我可以看到他们来自哪个表格。

SELECT 
   MIN(TableName) as TableName
   ,[strCustomer]
   ,[strAddress1]
   ,[strCity]
   ,[strPostalCode]
FROM 
   (SELECT 
       'Old' as TableName
       ,[JAS001].[dbo].[AR_CustomerAddresses].[strCustomer]
       ,[JAS001].[dbo].[AR_CustomerAddresses].[strAddress1]
       ,[JAS001].[dbo].[AR_CustomerAddresses].[strCity]
       ,[JAS001].[dbo].[AR_CustomerAddresses].[strPostalCode]
    FROM  
       [JAS001].[dbo].[AR_CustomerAddresses]
    UNION ALL
    SELECT 
       'New' as TableName
       ,[JAS001new].[dbo].[AR_CustomerAddresses].[strCustomer]
       ,[JAS001new].[dbo].[AR_CustomerAddresses].[strAddress1]
       ,[JAS001new].[dbo].[AR_CustomerAddresses].[strCity]
       ,[JAS001new].[dbo].[AR_CustomerAddresses].[strPostalCode]
    FROM 
       [JAS001new].[dbo].[AR_CustomerAddresses]) tmp
  GROUP BY 
     [strCustomer]
     ,[strAddress1]
     ,[strCity]
     ,[strPostalCode]
  HAVING 
     COUNT(*) = 1

This Stack Overflow Answer为我提供了一个更清晰的SQL查询,但没有告诉我这些行来自哪个表。

    SELECT * FROM [JAS001new].[dbo].[AR_CustomerAddresses]
    UNION 
    SELECT * FROM [JAS001].[dbo].[AR_CustomerAddresses]
    EXCEPT 
    SELECT * FROM [JAS001new].[dbo].[AR_CustomerAddresses]
    INTERSECT
    SELECT * FROM [JAS001].[dbo].[AR_CustomerAddresses]

我可以使用第一个版本,但我需要比较多个表,我认为必须有一种简单的方法将源表列添加到第二个查询。我已经尝试了几件事并且谷歌搜索无济于事。我怀疑也许我不是在寻找正确的东西,因为我确信之前已经回答过。

也许我走错了路,有更好的方法来比较数据库?

3 个答案:

答案 0 :(得分:2)

您可以使用以下设置来实现目标吗?

SELECT 'New not in Old' Descriptor, *
FROM 
  ( 
    SELECT * FROM [JAS001new].[dbo].[AR_CustomerAddresses]
    EXCEPT
    SELECT * FROM [JAS001].[dbo].[AR_CustomerAddresses]
  ) a

UNION 

SELECT 'Old not in New' Descriptor, *
FROM 
  (
    SELECT * FROM [JAS001].[dbo].[AR_CustomerAddresses]
    EXCEPT
    SELECT * FROM [JAS001new].[dbo].[AR_CustomerAddresses]
  ) b

答案 1 :(得分:0)

你不能在那里添加表名,因为union,除了和交集都比较所有列。这意味着您无法通过将表名添加到查询来区分它们。通过group by,您可以控制在查找重复项时考虑哪些列,以便排除表名。

为了帮助您比较需要比较的大量表,您可以从包含表名和列的元数据表中编写一个sql查询,并动态地生成这些值的SQL命令。

答案 2 :(得分:0)

使用下面的表名来派生一列

    SELECT MIN(TableName) as TableName
              ,[strCustomer]
              ,[strAddress1]
              ,[strCity]
              ,[strPostalCode]
          ,table_name_came
          FROM 
          (SELECT 'Old' as TableName
              ,[JAS001].[dbo].[AR_CustomerAddresses].[strCustomer]
              ,[JAS001].[dbo].[AR_CustomerAddresses].[strAddress1]
              ,[JAS001].[dbo].[AR_CustomerAddresses].[strCity]
              ,[JAS001].[dbo].[AR_CustomerAddresses].[strPostalCode]
              ,'[JAS001].[dbo].[AR_CustomerAddresses]' as table_name_came
          FROM [JAS001].[dbo].[AR_CustomerAddresses]
          UNION ALL
          SELECT 'New' as TableName
              ,[JAS001new].[dbo].[AR_CustomerAddresses].[strCustomer]
              ,[JAS001new].[dbo].[AR_CustomerAddresses].[strAddress1]
              ,[JAS001new].[dbo].[AR_CustomerAddresses].[strCity]
              ,[JAS001new].[dbo].[AR_CustomerAddresses].[strPostalCode]
          ,'[JAS001new].[dbo].[AR_CustomerAddresses]' as table_name_came
          FROM [JAS001new].[dbo].[AR_CustomerAddresses]
          ) tmp
          GROUP BY [strCustomer]
              ,[strAddress1]
              ,[strCity]
              ,[strPostalCode]
        ,table_name_came
            HAVING COUNT(*) = 1