【问题标题】:SQL query using EXIST operator - unexpected records in result使用 EXIST 运算符的 SQL 查询 - 结果中出现意外记录
【发布时间】:2016-06-03 04:21:12
【问题描述】:

使用 AdventureWorks2014 数据库,我正在试验 EXIST 关键字。请注意以下查询:

select p.color, p.productid, p.name, th.Quantity
from production.product p, production.TransactionHistory th
where p.ProductID=th.ProductID and EXISTS(
  select *
  from Production.TransactionHistory t
  where t.Quantity = 1000
  and t.ProductID=p.ProductID
)

我原本希望一次只能看到订购 1000 个的产品(只有一个交易满足此条件),但我得到了数百行 th.Quantity

从外部查询中删除连接的 TransactionHistory 表可以解决问题,但我只想知道为什么原始查询返回我看到的行。

谢谢

编辑:

为了澄清,我了解如何解决我想要的问题。我只是想了解 EXISTS 的行为以及为什么我没有得到预期的结果。

以下子查询(是 EXISTS 子查询的一部分)只返回一个结果。

select *
from Production.TransactionHistory t
where t.Quantity = 1000

因此,如果 this 在 EXISTS 中,它每次都会返回 true。需要注意的是,我在子查询中将 t.ProductID 与 p.ProductID 链接起来。因此,对于外部查询中的每一行,产品 ID 应该与内部查询中的产品 ID 匹配。 EXISTS 应该只在产品 ID 匹配并且数量正好为 1000 时返回 true。准确地说,EXIST 应该只在产品 ID 为 994 时返回 true,因为整个表中只有一个事务(具有该产品 ID)满足产品 ID 要求和 1000 个数量要求。

注意 EXISTS 子查询的其余部分...

where t.Quantity = 1000 and t.ProductID=p.ProductID

产品 ID 必须与外部记录的产品 ID 匹配,并且数量必须为 1000。

对我来说,这个查询说“给我所有产品的颜色、产品 id 和名称,加入交易,然后只包括交易表中至少有一条产品 id 与 id 匹配的记录的每一行CURRENT 外行,订单数量为 1000"。但这不是它的行为方式。只是想了解原因。

【问题讨论】:

  • 为了澄清,我了解如何解决我想要的问题。我只是想了解 EXISTS 的行为以及为什么我没有得到预期的结果。
  • 在一个简单的测试中,我没有得到意外的结果。你能提供样本数据吗?您的查询将所有记录从产品返回到历史连接,其中至少有一条历史记录的数量为 1000。因此,如果您看到 productid 994 的多条记录,这是有道理的,因为至少有一条数量为 1000,如果您看到的其他产品 ID 没有意义。
  • 产品 ID 相同,但我得到的结果是有交易数量 1000。我通过查看查询计划弄清楚了发生了什么。本质上,子查询返回 1 行使存在为真,但由于该产品 ID 有数百个其他事务,它们在外部查询的联接中被链接。

标签: sql sql-server


【解决方案1】:

您的查询听起来像这样:

如果任何历史条目有,则获取产品的所有交易历史条目 数量等于 1000。

EXISTS返回真假,所以

EXISTS(
    select *
    from Production.TransactionHistory t
    where t.Quantity = 1000
    and t.ProductID=p.ProductID
)

对于 TransactionHistory 的所有产品行返回 true,其中 Transaction with Quantity = 1000

另外:
上面的查询将针对“主要”查询的每一行执行,并将在您的案例中的每一行上返回 True。这就是你得到所有行的原因

【讨论】:

  • 所以 t.ProductID=p.ProductId 不匹配?整个数据库中只有一个产品与数量为 1000 的交易匹配。谢谢。
  • 但是该产品在 Transaction History 表中有多少行?您的查询返回所有行
  • 事务表中有 442 行与该产品 ID 匹配。但是,只有一行产品id匹配,数量为1000。
【解决方案2】:

EXISTS 如果以下查询中只有一条记录,则返回 true。 您正在寻找类似以下的查询:

SELECT p.color, p.productid, p.name, th.Quantity
FROM production.product p, production.TransactionHistory th
WHERE p.ProductID = th.ProductID and th.Quantity = 1000

或者你可以用更好看的join 查询替换它,如下所示:

SELECT p.color, p.productid, p.name, th.Quantity
FROM production.product p
INNER JOIN production.TransactionHistory th ON p.ProductID = th.ProductID 
WHERE th.Quantity = 1000

【讨论】:

  • 感谢 Chaos,感谢您的帮助。您能否阅读我上面的编辑?我完全掌握了查询的正确方法,但我想了解为什么我的实验查询失败了。
【解决方案3】:

这是因为您只检查 EXIST 子句中的 ProductID。当它找到至少一笔与您的 productID 相关的交易时,它会显示此类交易。因此,将显示交易数量等于 1000 的产品的所有交易。

【讨论】:

    【解决方案4】:

    基本上你的查询是在说

    给我所有产品及其交易历史 EVER 数量为 1000 的交易

    【讨论】:

      猜你喜欢
      • 2020-08-01
      • 1970-01-01
      • 2015-12-11
      • 2013-05-09
      • 2016-08-29
      • 2019-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多