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

在sql中查找两个表之间的重复差异,sql,sql-server,tsql,sql-server-2012,Sql,Sql Server,Tsql,Sql Server 2012,我试图在两个表之间找到重复的行。此代码仅在记录不重复时有效: (select [Name], [Age] from PeopleA except select [Name], [Age] from PeopleB) union all (select [Name], [Age] from PeopleB except select [Name], [Age] from PeopleA) 如何查找丢失的、重复的记录罗伯特34在人物角色表中,举例如下: 人物角色: Name | Age ---

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

(select [Name], [Age] from PeopleA
except
select [Name], [Age] from PeopleB)
union all
(select [Name], [Age] from PeopleB
except
select [Name], [Age] from PeopleA)
如何查找丢失的、重复的记录<代码>罗伯特34在
人物角色
表中,举例如下:

人物角色

Name   | Age
-------------
John   | 45
Robert | 34
Adam   | 26
Robert | 34
Name   | Age
-------------
John   | 45
Robert | 34
Adam   | 26
人员b

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

您可以使用
UNION ALL
合并两个表,并使用
Having
子句将
分组,以查找重复项:

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)

您可以使用
UNION ALL
将两个表合并,并使用
Having
子句将
分组以查找重复项:

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)

添加另一个
UNION ALL

代码:
添加另一个
UNION ALL

代码:
我喜欢蒂姆的答案,但如果记录丢失,你需要在两个表中都进行检查。他只是检查表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)

请参见此处的演示:

我喜欢Tim的答案,但如果缺少记录,则需要同时检查两个表。他只是检查表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)

请参见此处的演示:

我不明白您的要求是什么。您想查找出现在一个表中而不是另一个表中的记录,还是在单个表中查找重复记录?@ZoffDino Dino我想查找出现在一个表中而不是另一个表中的记录,包括重复记录<代码>除外
仅在记录不重复时显示差异。我需要类似于
'except all'
的东西来找到1对1的关系。对于表:
表1:John 23,Mike 17,John 23
表2:John 23,Mike 17
除了
没有显示差异,但这两个表不相同。我需要找到丢失的记录,这样当我将这些记录添加到表中时,两个表将是相同的,例如
表1:John 23、Mike 17、John 23
表1:John 23、Mike 17、John 23
。我不明白您的要求是什么。您想查找出现在一个表中而不是另一个表中的记录,还是在单个表中查找重复记录?@ZoffDino Dino我想查找出现在一个表中而不是另一个表中的记录,包括重复记录<代码>除外
仅在记录不重复时显示差异。我需要类似于
'except all'
的东西来找到1对1的关系。对于表:
表1:John 23,Mike 17,John 23
表2:John 23,Mike 17
除了
没有显示差异,但这两个表不相同。我需要找到丢失的记录,这样当我将这些记录添加到表中时,两个表将是相同的,例如
表1:John 23,Mike 17,John 23
表1:John 23,Mike 17,John 23
。你是西部最快的枪!当然比我快!:-)无论如何+1,因为我将给出基本相同的答案。@Tim Schmelter您的解决方案找到重复记录:
John 45
Robert 34
Adam 46
。我想在
PeopleB
表中查找缺少的记录-
robert34
。此记录在
peoard
中存在两次,但在
PeopleB
中仅存在一次。@TimSchmelter完美解决方案!非常感谢。@TimSchmelter。
left join
应该是
full outer join
,因此第二个表中的行(而不是第一个表)也包括在结果集中。@GordonLinoff:这一点很好,但我不确定这是否是OP的要求。然而,我已经把它包括在我的答案中。谢谢。你是西部最快的枪!当然比我快!:-)无论如何+1,因为我将给出基本相同的答案。@Tim Schmelter您的解决方案找到重复记录:
John 45
Robert 34
Adam 46
。我想在
PeopleB
表中查找缺少的记录-
robert34
。此记录在
peoard
中存在两次,但在
PeopleB
中仅存在一次。@TimSchmelter完美解决方案!非常感谢。@TimSchmelter。
left join
应该是
full outer join
,因此第二个表中的行(而不是第一个表)也包括在结果集中。@GordonLinoff:这一点很好,但我不确定这是否是OP的要求。然而,我已经把它包括在我的答案中。谢谢