需要找到2个结构相同的sql表之间的差异

Posted

技术标签:

【中文标题】需要找到2个结构相同的sql表之间的差异【英文标题】:need to find differences between 2 identically structured sql tables 【发布时间】:2010-05-05 12:15:42 【问题描述】:

我需要找出 2 个结构相同的 sql 表之间的差异 每个表都从 3rd paty 工具上传到 sqlserver 数据库中。

表结构为:

Issue ID-status-Who

问题 ID 不会在表中重复,尽管它没有明确定义为主键

任何两个表之间都可能有添加/删除/更新。

我需要什么

Number of rows added & their details
Number of rows deleted & their details
Number of rows updates & their details

我该怎么做

1) 使用sql更好吗 2)或使用数据表

【问题讨论】:

两张 相同 sql 表之间没有区别 ;-) 我无法抗拒! 您可以用 SQL 编写整个查询。但是,我看到“添加和删除”的一些问题。如果指定的行被添加或从另一个表中删除,您如何解决? @KM,我已经更正了标题以反映我的意思。希望现在适合你:) 【参考方案1】:

您可以使用两个左连接和常规连接来进行更新。这将向您显示相对于 TableA,添加、删除和更新了哪些行。请注意,这些可以包含在单个结果集中。

select b.*, 'added'
from tableb b
   left outer join tablea a on b.IssueID = a.IssueID
where a.IssueID is null

select a.*, 'deleted'
from tablea a
    left outer join tableb b on a.IssueID = b.IssueID
where b.IssueID is null

select a.*, 'updated'
from tablea a
    join tableb b on a.IssueID = b.IssueID
where a.Status <> b.Status or a.Who <> b.Who

注意后者,如果你需要处理空值,我认为你需要调整 where 子句。

如果表很大并且这是一个持续的操作,您应该考虑在连接列上添加索引。

【讨论】:

感谢您的快速回复,我错过了问题中的一点。更新的行数(我重复了删除部分)。你能帮忙吗? @KM -- 在我发布答案后,问题已被修改。要查找更新,您需要第三条语句。 我在一个声明中完成所有操作,请参阅我的答案***.com/questions/2773050/…【参考方案2】:

除非您想将每个表的全部内容复制到 C# 中,否则请在数据库中进行。

这将找到所有缺失的 TableA 或 TableB 行,以及任何更改:

;WITH AllPKs AS
(
SELECT ID FROM TableA
UNION ID FROM TableB
)
SELECT
    z.ID,a.*, b.*
    FROM AllPKs                z
        LEFT OUTER JOIN TableA a ON z.ID=a.ID
        LEFT OUTER JOIN Tableb b ON z.ID=b.ID
    WHERE A.ID IS NULL OR B.ID IS NULL OR a.Col1!=b.Col1 OR a.Col2!=b.Col2 OR...

【讨论】:

OP 没有说明他们使用的是哪个数据库,但如果他们不能使用 CTE,那么就将其设为派生表:SELECT z.ID,a.*, b.* FROM (SELECT ID FROM TableA UNION ID FROM TableB) z LEFT OUTER JOIN...【参考方案3】:

为了找到更新,您需要将每列的值与另一个表进行比较。

select 'updated',
   a.IssueID as IssueID_A, b.IssueID as IssueID_B
   a.Status as Status_A, b.Status as Status_B,
   a.Who as Who_A, b.Who as Who_B
from tablea a
inner join tableb b 
   on a.IssueID = b.IssueID 
where a.Status <> b.Status or a.Who <> b.Who

【讨论】:

这不会找到插入/删除【参考方案4】:

我听说过关于Redgate SQL Data Compare 的好消息

【讨论】:

您需要为此使用“数据比较”产品。 “比较”适用于模式。【参考方案5】:

一般来说,我会推荐像Redgate SQL Data Compare 这样的产品,但作为一次性产品,您可以使用这样的脚本:

-- Create some tables and data for testing purposes
USE [tempdb]
SET NOCOUNT ON
GO

DROP TABLE [Issues1]
DROP TABLE [Issues2]
GO

CREATE TABLE [Issues1] ([IssueID] int, [Status] varchar(max), [Who] varchar(max))
CREATE TABLE [Issues2] ([IssueID] int, [Status] varchar(max), [Who] varchar(max))
GO

INSERT [Issues1] VALUES (1, 'aaa', 'bbb')
INSERT [Issues1] VALUES (2, 'ccc', 'ddd')
INSERT [Issues1] VALUES (3, 'eee', 'fff')
GO

INSERT [Issues2] VALUES (1, 'aaa', 'bbb')
INSERT [Issues2] VALUES (3, 'ggg', 'hhh')
INSERT [Issues2] VALUES (4, 'iii', 'iii')
GO

-- **** START OF ANSWER PROPER ****

-- Create some temporary variables to store the change details
DECLARE @Inserts TABLE ([IssueID] int, [Status] varchar(max), [Who] varchar(max))
DECLARE @Updates TABLE ([IssueID] int, [OldStatus] varchar(max), [NewStatus] varchar(max), [OldWho] varchar(max), [NewWho] varchar(max))
DECLARE @Deletes TABLE ([IssueID] int, [Status] varchar(max), [Who] varchar(max))

-- Find all rows that exist in Issues2 but do not exist in Issues1
-- (matching on ID)
INSERT @Inserts
SELECT *
FROM [Issues2]
WHERE [IssueID] NOT IN
(
    SELECT
        [IssueID]
    FROM [Issues1]
)

-- Find all rows existing in both Issues1 and Issues2 (matching on ID)
-- and where either Status or Who has changed
INSERT @Updates
SELECT
    [Issues1].[IssueID],
    [Issues1].[Status],
    [Issues2].[Status],
    [Issues1].[Who],
    [Issues2].[Who]
FROM [Issues1]
    INNER JOIN [Issues2] ON [Issues2].[IssueID] = [Issues1].[IssueID]
        AND
        (
            [Issues2].[Status] != [Issues1].[Status]
                OR [Issues2].[Who] != [Issues1].[Who]
        )

-- Find all rows that exist in Issues1 but do not exist in Issues2
-- (matching on ID)
INSERT @Deletes
SELECT *
FROM [Issues1]
WHERE [IssueID] NOT IN
(
    SELECT
        [IssueID]
    FROM [Issues2]
)

-- Output the results
SELECT
    (SELECT COUNT(*) FROM @Inserts) AS [Number Inserted],
    (SELECT COUNT(*) FROM @Updates) AS [Number Updated],
    (SELECT COUNT(*) FROM @Deletes) AS [Number Deleted]

SELECT 'INSERTED', * FROM @Inserts
SELECT 'UPDATED', * FROM @Updates
SELECT 'DELETED', * FROM @Deletes
GO

【讨论】:

【参考方案6】:

如果您想要避免列出所有要比较的列并且想要包含 并输入相同的行,您可以执行以下操作:

--Data setup
d r o p table tableA;
d r o p table tableB;

create table tableA as (
   select rownum-1 ID, chr(rownum-1+70) bb, chr(rownum-1+100) cc 
      from dual connect by rownum<=4
);

create table tableB as (
   select rownum ID, chr(rownum+70) data1, chr(rownum+100) cc from dual
   UNION ALL
   select rownum+2 ID, chr(rownum+70) data1, chr(rownum+100) cc 
      from dual connect by rownum<=3
);

~

--View Tables.
select * from tableA;
select * from tableB;

~

--Solution.
with UnionedRows As
(
   select * from tableA 
   UNION 
   select * from tableB
)
select ID, sum(MyCount),  
   case 
      when sum(MyCount) = 12 then 'In Table A and Table B - Identical.'
      when sum(MyCount) =  2 then 'In Table A.'
      when sum(MyCount) = 13 then 'In Table A and Table B - Different.'
      when sum(MyCount) = 11 then 'In Table B.'
   end Status
from
(
   select ID, count(*) MyCount from UnionedRows group by ID
   UNION ALL
   select ID, 1 from tableA
   UNION ALL 
   select ID, 10 from tableB
) group by ID order by ID;

【讨论】:

以上是关于需要找到2个结构相同的sql表之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

查找 SQL 表之间的差异

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

[原]用SQL比较两张结构完全相同的表数据

在 MS Access 或 SQL Server 中查找 2 个表之间的差异

sql语句如何查询一个表中某两个字段的相同数据?

如何查看oracle 两个表结构是不是相同