Select命令中具有非聚集函数的聚集函数

时间:2019-04-18 14:35:04

标签: sql sql-server

我正在MS.SQL Server中进行编码。我在下面有一张小桌子:

INV_NUM  INV_AMOUNT
-------  ----------
8000        235       
8001        312 
8002        528
8003        194
8004        619

我想为将显示的所有发票编写查询:

  • 发票编号
  • 发票金额
  • 平均发票金额和
  • 平均发票金额与实际发票金额之差。

我的下面的代码:

SELECT I.INV_NUM,I.INV_AMOUNT,AVG(I.INV_AMOUNT) as AVERAGE,(AVG(INV_AMOUNT)-I.INV_AMOUNT) as DIFFER
FROM INVOICE I
GROUP BY I.INV_NUM,I.INV_AMOUNT;

MS SQL中的结果未生成avg值,而是在每行中显示INV_AMOUNT值。

结果是:

INV_NUM  INV_AMOUNT    Average      Differ 
--------- ------------------------------------
8003     194            194            0
8000     235            235            0
8001     312            312            0
8002     528            528            0
8004     619            619            0
--------------- -------------------------------

我发现表中只有一行,可以正常工作。 为什么会这样?谢谢!

2 个答案:

答案 0 :(得分:4)

我想你想要类似的东西:

select
  inv_num,
  inv_amount,
  avg(inv_amount) over() as average,
  avg(inv_amount) over() - inv_amount as diff
from invoice

您的查询将您的行分为不同的组。相反,您需要在单个组上使用窗口函数(使用OVER)。

结果:

inv_num  inv_amount  average  diff
-------  ----------  -------  ----
8000     235         377      142 
8001     312         377      65  
8002     528         377      -151
8003     194         377      183 
8004     619         377      -242

答案 1 :(得分:4)

您可以使用其他解决方案。正如Impaler所述,您可以使用窗口功能。为了更深入地了解这种实现方式,您应该阅读一些有关此的教程。 另一种方法是使用CTE。您将首先选择平均发票金额作为自己的查询。之后,您将在“主”查询中使用它。看起来像这样:

WITH avg_inv AS
(
select avg(inv_amount) average
)
select
  inv_num,
  inv_amount,
  (select average from avg_inv) as average,
  (select average from avg_inv) - inv_amount as diff
from invoice;