我需要找到2个结构相似的sql表之间的差异 每个表都从第3个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)或使用数据表
答案 0 :(得分:3)
您可以使用两个左连接和常规连接来执行此更新。对于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子句。
如果表很大并且这是一个持续的操作,您应该考虑在连接列上添加索引。
答案 1 :(得分:0)
除非您想将每个表的全部内容复制到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...
答案 2 :(得分:0)
我听说过有关Redgate SQL Data Compare
的好消息答案 3 :(得分:0)
要查找更新,您需要将每列的值与另一个表进行比较。
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 :(得分:0)
一般情况下,我会推荐像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
答案 5 :(得分:0)
如果您想避免列出要比较的所有列以及是否要包含 并输入相同的行,您可以执行以下操作:
--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;