【问题标题】:Compare two tables, find missing rows and mismatched data比较两个表,查找缺失的行和不匹配的数据
【发布时间】:2013-04-02 08:37:48
【问题描述】:

我想比较两个表并获得一组结果,其中查找值不匹配以及另一个表中缺少键值。第一部分适用于以下查询:

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)。

如何在同一个查询中实现两者?

【问题讨论】:

  • 您使用的是什么数据库系统?

标签: sql


【解决方案1】:

删除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

【讨论】:

    【解决方案2】:

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

    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 子句保留所有行,其中一侧或另一侧为空,并且在它们匹配的位置(都不为空),仅保留“查找”值不同的那些行。

    【讨论】:

      【解决方案3】:

      从 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
      

      【讨论】:

      • EXCEPT 从左输入查询返回不由右输入查询输出的不同行。 Reference
      猜你喜欢
      • 2016-05-11
      • 1970-01-01
      • 2021-12-23
      • 2017-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多