【问题标题】:Query to find the mismatched records in two tables without a primary key查询在没有主键的两个表中查找不匹配的记录
【发布时间】:2021-07-22 09:11:24
【问题描述】:

我想使用完全外连接和 where 子句(查询如下)从两个表(如下所示)中选择不匹配的记录。这两个表都没有主键。我认为由于外部连接,我得到了结果中的所有 3 条记录。有没有办法通过修改查询只返回不匹配的记录? (即第三条记录)。

表1:

表2:

使用的查询:

    DECLARE @table1 TABLE  (element_type varchar(100),element_code  varchar(100), value varchar(100))
    DECLARE @table2 TABLE  (element_type varchar(100),element_code  varchar(100), value varchar(100))
    
    Insert into @table1
    values
    ('ABC', 'CODE1', 'Interest Due'),
    ('ABC', 'CODE1', NULL),
    ('BCD', 'CODE2', 'value1')
    
    Insert into @table2
    values
    ('ABC', 'CODE1', 'Interest Due'),
    ('ABC', 'CODE1', NULL),
    ('BCD', 'CODE2', 'value2')
    
    SELECT  
            [Element Type] = ISNULL(m1.element_type, m2.element_type),
            [Differences]  = 'value missmatch'
        FROM    
            @table1 m1 
            FULL OUTER JOIN @table2 m2 
                ON m1.element_type = m2.element_type AND m1.element_code = m2.element_code
        WHERE
        ISNULL(m1.value, '') <> ISNULL(m2.value, '')

输出:

期望的输出:

【问题讨论】:

  • 我希望这会返回五条记录。如果您将示例数据作为插入语句包含在内,这个问题会更好
  • 根据问题指南,请不要发布代码、数据、错误消息等的图像 - 将文本复制或输入到问题中。请保留将图像用于图表或演示渲染错误,无法通过文本准确描述的事情。
  • @Nick.McDermaid - 我已经用插入语句更新了查询。
  • 我能想到的唯一方法是找到所有完全匹配的记录,然后将它们从不匹配过程中排除。
  • 这基本上是一个EXCEPT ALL 查询,但 SQL Server 不支持该语法

标签: sql sql-server tsql


【解决方案1】:

Set Operators - EXCEPT and INTERSECT

WITH result AS (
  (SELECT * FROM @table1 UNION SELECT * FROM @table2)
  EXCEPT
  (SELECT * FROM @table1 INTERSECT SELECT * FROM @table2)
)
SELECT DISTINCT element_type, element_code, 'value missmatch' AS Differences
FROM result;

fiddle

【讨论】:

    【解决方案2】:

    将所有列包含在关于可空性的 ON 子句中

    SELECT  distinct
            [Element Type] = ISNULL(m1.element_type, m2.element_type),
            [Differences]  = 'value missmatch'
        FROM    
            table1 m1 
            FULL OUTER JOIN table2 m2 
                ON m1.element_type = m2.element_type 
                   AND m1.element_code = m2.element_code 
                   AND (m1.value = m2.value or m1.value IS NULL and m2.value IS NULL)
        WHERE m1.element_type IS NULL OR m2.element_type IS NULL
    

    【讨论】:

      【解决方案3】:

      您的问题不清楚,但下面的查询会产生您想要的输出。

      SELECT  
             [Element Type] = m1.element_type,
                 [Differences]  = 'value missmatch'
             FROM    
                  @table1 m1 
                  Left JOIN @table2 m2 
                      ON m1.element_type = m2.element_type AND m1.element_code = m2.element_code AND m1.value != m2.value
      WHERE m1.value IS NOT NULL AND m2.value IS NOT NULL
      

      【讨论】:

      • table2 ('BCD', 'CODE2', NULL) 是一个不起作用的例子。
      猜你喜欢
      • 2012-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多