比较两个表,查找丢失的行和不匹配的数据

时间:2013-04-10 13:16:13

标签: sql

我想比较两个表并得到一组结果,其中查找值不匹配,以及其他表中缺少键值的位置。第一部分可以正常使用以下查询:

SELECT * FROM (
    SELECT  mID, mLookup
    FROM m) t1

FULL OUTER JOIN (
    SELECT  aID, aLookup
    FROM a) t2

ON t1.mID = t2.aID

WHERE
    t1.mID = t2.aID AND
    t1.mLookup <> t2.aLookup

但是,它不返回t1和t2中的行,而另一个表中没有相应的ID(因为ON t1.mID = t2.aID)。

如何在同一个查询中同时实现这两个目标?

3 个答案:

答案 0 :(得分:7)

删除WHERE子句的ID部分。 FULL OUTER JOIN ON t1.mID = t2.aID足以将表格链接在一起。即使没有匹配,FULL OUTER JOIN也会返回连接中的两个表。

但是,WHERE t1.m_ID = t2.aID子句将结果限制为两个表中存在的ID。这有效地使FULL OUTER JOININNER JOIN一样行动。

换句话说:

SELECT * FROM (
    SELECT  mID, mLookup
    FROM m) t1

FULL OUTER JOIN (
    SELECT  aID, aLookup
    FROM a) t2

ON t1.mID = t2.aID

WHERE
    --t1.mID = t2.aID AND -- remove this line
    t1.mLookup <> t2.aLookup

- 编辑 -

重新阅读你的问题,你只想要不匹配。在这种情况下,您需要搜索任何一方的ID为NULL的位置:

SELECT * FROM (
    SELECT  mID, mLookup
    FROM m) t1

FULL OUTER JOIN (
    SELECT  aID, aLookup
    FROM a) t2

ON t1.mID = t2.aID

WHERE
    t1.mID IS NULL OR
    t2.mID IS NULL OR
    t1.mLookup <> t2.aLookup

答案 1 :(得分:3)

查询的where子句过滤掉那些没有匹配“Ids”的行。试试这个:

SELECT m.mId, m.mLookup, a.aId, a.aLookup
 from m
  full outer join a
   on a.aId = m.mId
 where m.mId is null
  or a.aID is null
  or m.mLookup <> a.aLookup

完整的外部联接获取所有可能的行,而where子句保留所有行,其中一个或另一个为空,并且它们匹配(均为空),仅保留“查找”值不同的那些行。 / p>

答案 2 :(得分:0)

从SQL Server 2008开始,并且对Azure SQL数据库,Azure SQL数据仓库,并行数据仓库有效

以下是SQL查询;

USE [test]
GO

CREATE TABLE [dbo].[Student1](
    [Id] [int] NOT NULL,
    [Name] [nvarchar](256) NOT NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Student2](
    [Id] [int] NOT NULL,
    [Name] [nvarchar](256) NOT NULL
) ON [PRIMARY]
GO

---- You can re-run from here with your data 
truncate table [Student1]
truncate table [Student2]

insert into [Student1] values (1, N'سید حیدر')
insert into [Student1] values (2, N'Syed Ali')
insert into [Student1] values (3, N'Misbah Arfin')

insert into [Student2] values (2, N'Syed Ali')
insert into [Student2] values (3, N'Misbah Arfin');

with StudentsAll (Id, [Name]) as
(
select s1.Id, s1.[Name] from Student1 s1
    left outer join Student2 s2 
on 
    s1.Id = s2.Id
),
StudentsMatched (Id, [Name]) as
(
select s1.Id, s1.[Name] from Student1 s1
    inner join Student2 s2 
on 
    s1.Id = s2.Id
)
select * from StudentsAll
except
select * from StudentsMatched