【问题标题】:EXISTS and less than producing different result from NOT EXISTS and greater thanEXISTS 和小于与 NOT EXISTS 和大于产生不同的结果
【发布时间】:2015-10-30 08:58:37
【问题描述】:

我在 AdventureWorks2012 数据库中使用 SQL Server 2014 Express,通过 T-SQL 教科书学习。我正在做以下练习:

Delete the rows from the dbo.demoCustomer table if the sum of the TotalDue     
from the dbo.demoSalesOrderHeader table for the customer is less than $1,000. 

我使用 CTE 得出以下答案。它从表中删除 5200 行。

;with broke as
   (select c.customerid
   , sum(soh.totaldue) 'custtotal'
   from democustomer c
   inner join demosalesorderheader soh on soh.customerid = c.customerid
   group by c.customerid
   having sum(soh.totaldue) < 1000)
delete c
from democustomer c
where exists
   (select *
   from broke b
   where b.customerid = c.customerid);

我检查了 texbook 的答案,它给出了以下内容。与我的查询不同,它删除了 5696 行,比我自己的多 496 行。

delete c
from dbo.democustomer c
where not exists
   (select *
   from dbo.demosalesorderheader soh
   where c.customerid = soh.customerid
   group by soh.customerid
   having sum(totaldue) >=1000);

如果我改变我的方法并将not existshaving sum(totaldue) &gt;= 1000 一起使用,它也会产生5696 行。我不明白为什么查询会产生不同的结果 - EXISTS&lt; 1000 不应该产生与 NOT EXISTS&gt;=1000? 相同的结果

我查看了出现在NOT EXISTS&gt;=1000 版本中的 496 行,并确定customerid 不存在于salesorderheader 表中(即他们没有下订单)。但是为什么NOT EXISTS 版本会捕获这个而EXISTS 没有呢?

【问题讨论】:

  • 你试过看看有多少订单的总和=1000?
  • @vkp 没有一个分组的总和 = 1000。我会发布查询,但看起来 cmets 不允许格式化 - 如果您希望我发布它,请告诉我。

标签: sql sql-server exists sql-server-2014 not-exists


【解决方案1】:

评论太长了。

您了解问题所在,即 demosalesorderheader 中的 NULL/缺失值。

你的版本,你说exists,要求客户既存在于表中并且总和小于1000。

替代版本不以表中存在客户为条件。大概,默认值为0。

您可以更改查询以获得相同的结果:

with broke as (
     select c.customerid, coalesce(sum(soh.totaldue), 0) as custtotal
     from democustomer c left join
          demosalesorderheader soh
          on soh.customerid = c.customerid
     group by c.customerid
     having coalesce(sum(soh.totaldue), 0) < 1000
    )

left join 将保留所有客户。

【讨论】:

  • 等待有人找到原因。幸运的是你在这里:D
  • @Gordon Linoff 让我看看我是否明白了。正如您所说,使用 NOT EXISTS 的“替代”版本基本上会带来两组 - 那些在两个表中且总和不 >= 1000 的组,以及不在两个表中的组。替代捕获的是后一组,而我原来的组丢失了 - 对吗?
  • 为了进一步确认我的理解,不在两个表中的人将被删除的确切原因是因为他们的 sum(totaldue) 为 NULL,这不满足 sum(totaldue) 的 EXISTS 条件
  • @JulianDrago 。 . .不完全的。没有记录的人根本不在子查询中,所以exists 失败。
猜你喜欢
  • 1970-01-01
  • 2015-02-17
  • 2011-05-26
  • 2021-08-29
  • 2013-11-18
  • 1970-01-01
  • 1970-01-01
  • 2018-11-15
  • 1970-01-01
相关资源
最近更新 更多