Sql 在Select中重用聚合

Sql 在Select中重用聚合,sql,sql-server,Sql,Sql Server,在下面的查询中,SQL是否需要计算两次SUM(MY_INDICATOR)(每个字段使用一次),或者是否优化为只执行一次聚合 SELECT ID, SUM(MY_INDICATOR) AS MY_SUM, SUM(MY_INDICATOR) / COUNT(*) AS MY_RATE FROM SOMETABLE GROUP BY ID 更新:在查看了一些执行计划Thorsten是否正确后,SQL Server优化器将生成一个执行计划,该执行计划只需要执行一次SUM(MY_I

在下面的查询中,SQL是否需要计算两次
SUM(MY_INDICATOR)
(每个字段使用一次),或者是否优化为只执行一次聚合

SELECT
  ID,
  SUM(MY_INDICATOR) AS MY_SUM,
  SUM(MY_INDICATOR) / COUNT(*) AS MY_RATE
FROM
  SOMETABLE
GROUP BY
  ID

更新:在查看了一些执行计划Thorsten是否正确后,SQL Server优化器将生成一个执行计划,该执行计划只需要执行一次
SUM(MY_INDICATOR)
。优化查询不需要CTE。

它需要计算两次,您可以这样做,因此只需计算一次:

SELECT ID, MY_SUM, 
       MY_SUM / MY_COUNT AS MY_RATE
FROM ( SELECT ID,
              SUM(MY_INDICATOR) AS MY_SUM,
              COUNT(*) AS MY_COUNT
       FROM  SOMETABLE
       GROUP BY ID
     ) t;

您担心的是一个非常不相关的优化。聚合查询的代价是读取数据并重新排列数据,以便可以同时处理公共键值。简单的
sum()
不是性能问题

也就是说,假设
my_指示符
不是
NULL
,您可以将逻辑简化为:

SELECT ID, SUM(MY_INDICATOR) AS MY_SUM,
       AVG(MY_INDICATOR * 1.0) AS MY_RATE
FROM SOMETABLE
GROUP BY ID;
之所以使用
*1.0
,是因为SQL Server执行整数运算——为了避免(即使在您的版本中)需要转换为带小数点的数字格式

我经常将这种逻辑写成:

avg(case when my_indicator = 1 then 1.0 else 0 end)

你检查过执行计划了吗?您可能可以跟踪计算机标量运算符以找到答案。DBMS不太可能两次执行该计算。数据库管理系统中有一个优化器,这是一个非常容易检测和优化的案例。不管怎样,别担心。信任数据库管理系统尽其所能,通常情况下就是这样。你为什么要使用
SUM(MY_INDICATOR)/COUNT(*)
?对于内置的
AVG
函数,这看起来可能是一个不正确的(存在null)替换。问题与语法无关。你可以用任何让你高兴的聚合来替换SUM(我的指数)…很有可能它会对它进行多次评估。大多数情况下,它不会产生任何明显的差异,但它有可能产生这样的场景。有没有办法用执行计划或定时试验查询来证明这一点?我不确定执行计划,但对于定时试验查询,您可以,但必须有足够大的数据集来显示任何可识别的差异。如果这样做,还必须考虑任何兑现的执行计划等。我不同意你的分析。具体而言,总和对问题并不重要。我可以用一些非常昂贵的聚合来代替SUM(我的_指标),然后问同样的问题。语法不是我要问的。