2

以下有问题吗?

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
    )
4

1 回答 1

2

省略 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]
于 2012-08-20T10:52:50.497 回答