繁体   English   中英

在SQL中查找两个表之间的重复差异

[英]Finding duplicate differences between two tables in sql

我尝试在两个表之间找到重复的行。 仅当记录不重复时,此代码才有效:

(select [Name], [Age] from PeopleA
except
select [Name], [Age] from PeopleB)
union all
(select [Name], [Age] from PeopleB
except
select [Name], [Age] from PeopleA)

如何查找丢失的重复记录。 下面的PersonA表中的Robert 34

人物角色

Name   | Age
-------------
John   | 45
Robert | 34
Adam   | 26
Robert | 34

人B

Name   | Age
-------------
John   | 45
Robert | 34
Adam   | 26

您可以使用UNION ALL合并两个表,并使用Having子句的Group By查找重复项:

SELECT x.Name, x.Age, Cnt = Count(*) 
FROM (   
    SELECT a.Name, a.Age
    FROM PersonA a

    UNION ALL

    SELECT b.Name, b.Age
    FROM PersonB b  
) x
GROUP BY x.Name, x.Age
HAVING COUNT(*) > 1

根据您的澄清的评论,你可以使用下面的查询来查找所有名年龄组合PersonA ,其在不同PersonB

WITH A AS(
   SELECT a.Name, a.Age, cnt = count(*)
   FROM PersonA a
   GROUP BY a.Name, a.Age
),
B AS(
   SELECT b.Name, b.Age, cnt = count(*)
   FROM PersonB b
   GROUP BY b.Name, b.Age
)
SELECT a.Name, a.Age
FROM A a LEFT OUTER JOIN B b
  ON a.Name = b.Name AND a.Age = b.Age
WHERE a.cnt <> ISNULL(b.cnt, 0)

演示版


如果您还想查找PersonB但不在PersonA中的PersonA ,则应使用FULL OUTER JOIN如Gordon Linoff所说:

WITH A AS(
   SELECT a.Name, a.Age, cnt = count(*)
   FROM PersonA a
   GROUP BY a.Name, a.Age
),
B AS(
   SELECT b.Name, b.Age, cnt = count(*)
   FROM PersonB b
   GROUP BY b.Name, b.Age
)
SELECT Name = ISNULL(a.Name, b.Name), Age = ISNULL(a.Age, b.Age)
FROM A a FULL OUTER JOIN B b
  ON a.Name = b.Name AND a.Age = b.Age
WHERE ISNULL(a.cnt, 0) <> ISNULL(b.cnt, 0)

演示版

我喜欢蒂姆的答案,但如果记录缺失,则需要在两个表中都进行检查。 他只是在检查表A中是否缺少记录。尝试执行此操作以检查两个表中的任何一个记录是否都丢失了多少次。

Select *, 'PersonB' MissingInTable, a.cnt - isnull(b.cnt,0) TimesMissing From 
(
Select *, count(1) cnt from PersonA group by Name, Age) A Left join 
(Select *, count(1) cnt from PersonB group by Name, Age) B
On a.age=b.age and a.name=b.name
where a.cnt>isnull(b.cnt,0)

Union All

Select *, 'PersonA' MissingInTable, b.cnt - isnull(a.cnt,0) TimesMissing From 
(
Select *, count(1) cnt from PersonA group by Name, Age) A Right join 
(Select *, count(1) cnt from PersonB group by Name, Age) B
On a.age=b.age and a.name=b.name
where b.cnt>isnull(a.cnt,0)

在此处查看演示: http : //sqlfiddle.com/#!6/06020/13

添加另一个UNION ALL

码:

(SELECT [Name], [Age], 'Missing from B' AS [Type] from PeopleA
EXCEPT
SELECT [Name], [Age], 'Missing from B' AS [Type] from PeopleB)
UNION ALL
(SELECT [Name], [Age], 'Missing from A' as [Type] from PeopleB
EXCEPT
SELECT [Name], [Age], 'Missing from A' AS [Type] from PeopleA)
UNION ALL
SELECT [Name], [Age], 'Duplicate' AS [Type] FROM PeopleA INNER JOIN PeopleB ON PeopleA.Name = PeopleB.Name AND  
PeopleA.Age=PeopleB.Age

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM