【问题标题】:TSQL - LEFT JOIN strange resultsTSQL - LEFT JOIN 奇怪的结果
【发布时间】:2020-07-29 13:43:53
【问题描述】:

我遇到了一个看似基本的查询结果的问题(在 SQL Server 2017 CU17 上),我希望人们可以提出一些我可能没有检查过或试图得到正确结果的事情。

问题的前提是我试图识别一个表中的行,其中 ID 存在于另一个表中。这通常可以通过 LEFT JOIN 来完成,在这种情况下,查询如下所示:

SELECT  t1.id,
        t2.id
FROM Table1 AS t1
LEFT JOIN Table2 t2 ON t2.id = t1.id
WHERE t2.id IS NULL

此查询应根据“id”列识别 Table1 中存在但在 Table2 中不存在的行,并针对在我运行查询时未以任何方式操作的静态数据运行。

我得到了一个奇怪的结果,其中返回了 t1.id 的行,但 t2.id 为 NULL - 好像 t1 中存在行,但 t2 中不存在行。 但是,如果我采用从第一个查询返回的 ID 之一,并手动检查它是否存在于两个表中,看起来 id 确实存在于两个表中 - 即使我将该 id 放入具有内部连接的查询中,例如如下:

SELECT  t1.id,
        t2.id
FROM Table1 AS t1
INNER JOIN Table2 t2 ON t2.id = t1.id
WHERE t1.id = 761179370

如果我多次运行 LEFT JOIN 查询,每次返回的行数都不同。 需要注意的是,id 列都是 int 数据类型,并且表具有完全相同的排序规则。

我尝试过的:

  • 我已经为每个表重建了所有列和索引的统计信息,看看这是否会导致一些问题。
  • 我已将数据库恢复到另一台服务器并运行相同的程序,但没有遇到我在上面看到的问题。该数据库位于可用性组中,我还在可读辅助数据库上运行了相同的查询,但没有看到相同的行为。
  • 我运行 LEFT JOIN 查询的服务器已打开,总体上是一个繁忙的服务器 - 这可能是查询未返回正确结果的一个因素吗?
  • 我尝试过开启和关闭 ANSI_NULLS,没有区别。

知道问题可能是什么,或者我可以检查什么以找出我得到这些结果的原因 - 任何指导都将不胜感激!

【问题讨论】:

  • 一种可能是数据只是在变化,所以没有稳定的结果。另一个是表格实际上是不返回稳定结果的视图。
  • 谢谢戈登。它们绝对是表而不是视图。我在数据是静态的时候测试了查询,没有任何改变,甚至改变了查询的隔离级别以在查询期间保持对表的锁定。
  • @JamesG,如果可能的话,复制有问题的表(如果它们很大,则复制一份),这样表就不会收到更新。然后重试测试,我认为 Gordon 是正确的,但这是确认这一点的一种方法。
  • @JamesG 查询SELECT t1.id, t2.id FROM Table1 AS t1 INNER JOIN Table2 t2 ON t2.id = t1.id WHERE t2.id = 761179370 的结果是什么?我将WHERE中的 t1 更改为 t2@
  • @Ryan - 我已将数据库恢复到新服务器上 - 我没有看到同样的问题,所以问题似乎出在恰好在生产中的一台服务器上。 Gordon 建议的是我几天前测试的第一件事,确保数据是静态的。

标签: sql sql-server tsql


【解决方案1】:

不久前我遇到了类似的问题。原因是 SQL-Server Management Studio 缓存了一些结果。著名的断断续续确实解决了我的问题。您的实验几乎表明情况并非如此,所以..

在这里我建议将结果与以下内容进行比较:

SELECT  t1.id FROM Table1 AS t1
where t1.id not in (select id from table2)

如果这些结果与您的查询不匹配,我建议重新启动。

PS:很抱歉没有使用评论,我没有足够的声誉。 :-\

【讨论】:

    【解决方案2】:

    如果您发布真正的查询,我们可能会在此处看到错误,再次检查查询,左连接中的某些条件可能会改变“通常的逻辑”。

    如果还是错了,试试这个:

    SELECT
    t1.id,
    t2.id
    FROM Table1 AS t1
    LEFT JOIN Table2 t2 ON t2.id = t1.id
    WHERE t2.id IS NULL
    option (recompile) --> This will ignore any cached data
    

    或者创建2个临时存储一些数据并在那里测试,生产中的数据库可能会很快改变结果。

    【讨论】:

      猜你喜欢
      • 2019-07-21
      • 2016-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-29
      • 1970-01-01
      • 1970-01-01
      • 2019-09-06
      相关资源
      最近更新 更多