比较与特定字段有关的两个表之间的差异时如何正确连接

Posted

技术标签:

【中文标题】比较与特定字段有关的两个表之间的差异时如何正确连接【英文标题】:How to properly join when comparing the difference between two tables pertaining to specific fields 【发布时间】:2017-11-27 19:22:38 【问题描述】:

我在编写此查询时遇到问题。所以我将一个临时表与我们数据库中的一个表进行比较。我想找到两个表之间没有相同 Case_Number 相同 Id_Number 组合的任何记录。我正在使用的查询仅根据我加入它们的方式为我提供一种或另一种。如果我通过 Case_Number 加入,它将返回两个表之间不匹配的 Case_Number 记录。如果我通过 Id_Number 加入,它将返回两个表之间不匹配的 Id_Numbers。有没有办法同时通过 Case_Number 和 ID_Number 加入,以便查询返回两者?我还想知道是否可以在查询中包含“如果存在”?代码如下

 SELECT T1.Case_Number, T1.Id_Number, T1.FirstDate, T1.LastDate, T2.Case_Number, T2.Id_Number, T2.FirstDate, T2.LastDate
    FROM dbo.table T
    inner join #TempTable T2
     on T1.Id_Number = T2.Id_Number
    --on T1.Case_Number = T2.Case_Number
    where T1.LastDate is null
     and T1.Case_Number <> T2.Case_Number
     OR T1.Id_number <> T2.Id_Number

【问题讨论】:

请选择 mysql 或 SqlServer - 它们有不同的语法。选择您使用的那个。 我认为您需要查看左连接。并在 where 谓词中添加一些括号,否则您的逻辑可能不正确。 【参考方案1】:

inner join 语句中使用or

SELECT T1.Case_Number,
       T1.Id_Number,
       T1.FirstDate,
       T1.LastDate,
       T2.Case_Number,
       T2.Id_Number,
       T2.FirstDate,
       T2.LastDate
FROM dbo.table T
INNER JOIN #TempTable T2 ON (T1.Id_Number = T2.Id_Number
                             OR T1.Case_Number = T2.Case_Number)
WHERE T1.LastDate IS NULL
  AND T1.Case_Number <> T2.Case_Number
  OR T1.Id_number <> T2.Id_Number

【讨论】:

【参考方案2】:

这应该找到两者 - 第一个列告诉你是什么情况

(
    SELECT 'in Table not in Temp' as R,
        T1.Case_Number as 'T1.Case_Number', 
        T1.Id_Number as 'T1.Id_Number', 
        T1.FirstDate as 'T1.FirstDate', 
        T1.LastDate as 'T1.LastDate', 
        null as 'T2.Case_Number', 
        null as 'T2.Id_Number', 
        null as 'T2.FirstDate', 
        null as 'T2.LastDate'
    FROM dbo.table T1 
    where not exists ( 
        select 1 
        from #TempTable T2 
        where T1.Case_Number == T2.CaseNumber
          and T1.Id_Number == T2.Id_Number)
) 
UNION ALL 
(
    SELECT 'in temp, not in list' as R
        null as 'T1.Case_Number', 
        null as 'T1.Id_Number',  
        null as 'T1.FirstDate',  
        null as 'T1.LastDate', 
        T2.Case_Number as 'T2.Case_Number',  
        T2.Id_Number as 'T2.Id_Number',  
        T2.FirstDate as 'T2.FirstDate',  
        T2.LastDate as 'T2.LastDate'
    FROM #TempTable T2 
    where not exists ( 
        select 1 
        from dbo.table T1 
        where T1.Case_Number == T2.CaseNumber
          and T1.Id_Number == T2.Id_Number )

)

添加T1.LastDate is null - 不确定你想要它。

您可能需要调整列名,我将 T1/T2 切换为第二条语句,因此列将始终是同一个表,但名称有重复。

【讨论】:

这会返回错误状态:无法绑定多部分标识符“字段”。对于查询的第一部分,无法绑定 T2 字段,对于查询的第二部分,无法绑定 T1 字段 @User812372 你说得对 - 我试图纠正它。您不再加入表(如果根本不匹配,这没有意义) - 因此每个语句都知道 T1 或 T2。如果没有两个表的 ddl,很难编写有效的 dml 选择。想法是:第一条语句为您提供 dbo.table 中仅包含在其中的所有内容,并为其他值提供 dummy-columns,第二条语句为您提供仅在 #temtbl 中的所有内容,其中包含 T1 的 dummycolums 和 union all一次性为您提供所有这些。其他答案对你有用吗? 另一个答案对我不起作用,但我相信我可能已经找到了让它起作用的方法。我把我原来的查询放在你的里面。两个部分都使用相同的查询,只是连接方式不同。查询的第一部分,我加入了 case_number,第二部分加入了 id_number。这会同时返回 case_number 和 id_number 不匹配

以上是关于比较与特定字段有关的两个表之间的差异时如何正确连接的主要内容,如果未能解决你的问题,请参考以下文章

如何比较两个表数据的差异

Mysql某个表有近千万数据,CRUD比较慢,如何优化?

内连接与外连接

显示来自两个不同表的两列之间的差异(比较表)

内连接与外连接-及其典型案例

比较特定位置的两个日期之间的日期