在Select中重用聚合

时间:2018-05-30 18:26:13

标签: 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_INDICATOR)执行一次的执行计划。优化查询不需要CTE。

2 个答案:

答案 0 :(得分:0)

您担心的优化是无关紧要的。聚合查询的费用是读取数据并重新排列,以便可以同时处理常用键值。简单的sum()不是性能问题。

也就是说,假设my_indicator不是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)

答案 1 :(得分:-1)

它必须计算两次,你可以这样做,所以你只需要计算一次:

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;