sql - 通常会出现错误,但在 EXISTS 子查询中运行

标签 sql sql-server-2008-r2

以下有问题吗?

DELETE a
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData a
WHERE EXISTS
        (
        SELECT * 
        FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData b
        WHERE 
            b.[Past28Days] = 1 AND
            a.[Index] = b.[Index]
        HAVING SUM(b.Amount) = 0
        )

我对使用上述脚本感到有点不安的原因是,如果我运行以下脚本,则会出现错误:

SELECT * 
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData b
WHERE 
    b.[Past28Days] = 1
HAVING SUM(b.Amount) = 0

我明白为什么这个脚本会出错 => 选择没有对任何内容进行分组,因此处理器不喜欢 HAVING 子句中的聚合。

但是作为子查询,这个错误不会发生 - 为什么?这是一个有问题的方法吗?

编辑

最终使用了以下内容:

DELETE a
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData a
WHERE a.[Index] IN
    (
    SELECT [Index] 
    FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData
    WHERE [Past28Days] = 1
    GROUP BY [Index] 
    HAVING SUM(Amount) = 0
    )

但正如答案中所建议的,通过简单地将 GROUP BY 添加到子查询中,以下内容更具可读性:

DELETE a
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData a
WHERE EXISTS
    (
    SELECT * 
    FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData b
    WHERE 
            b.[Past28Days] = 1 AND
            a.[Index] = b.[Index]
    GROUP BY b.[Index]
    HAVING SUM(b.Amount) = 0
    )

最佳答案

省略 group by 并仍然执行聚合是合法的,因此 having 仍然是限制结果的一种方式:

select sum(x)
from
(
  select 1 x union all select 2
) a
having sum(x) = 3

Exists() 有效,因为选择列表中的所有内容都被忽略。 Exists() 仅查找行,并在找到行后立即终止。您可以添加 group by b.Index 以使稍后查看代码的任何人都清楚其意图,或者使用内部联接和派生表重写它。

DELETE a
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData a
INNER JOIN
        (
        SELECT b.[Index]
        FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData b
        WHERE 
            b.[Past28Days] = 1
        GROUP BY b.[Index]
        HAVING SUM(b.Amount) = 0
        ) b1
   ON a.[Index] = b1.[Index]

关于sql - 通常会出现错误,但在 EXISTS 子查询中运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12036149/

相关文章:

sql - 每条记录的倒数第二个日期

mysql - 使用 MYSQL Workbench 查询将数据 (DATETIME) 加载到 MySQL 中时出现错误 1265

sql-server - SQL Server 查询 XML xpath 空命名空间

具有唯一值的 SQL Server COUNT 查询

SQL Server INSTEAD OF INSERT 触发器失败

sql - SAS、proc Summary 中哪个统计计算速度更快?

java - 为什么 SQL select 在 java 中需要更多的 CPU 时间?

python - 使用Python sqlite3,我应该在任何SQL操作和commit()之后使用sleep()吗?

sql - 如何将动态列添加到现有表

sql - 在 DELETE 中使用 CTE 未执行