为什么这个SQL SUM语句是正确的?

时间:2010-08-03 18:47:10

标签: sql sum

在我的架构中,我有一个表Projects和一个表Tasks。每个项目都包含任务。每个任务都有小时和百分比完成。

示例表:

ProjectID    TaskID    Hours   PercentComplete
1            1         100     50
1            2         120     80

我正在尝试为项目完成加权百分比。我使用以下SQL语句执行此操作:

SELECT P.ProjectID, P.ProjectName, SUM(T.Hours) AS Hours, 
SUM(T.PercentComplete * T.Hours) / 100 AS CompleteHours, 
SUM(T.PercentComplete * T.Hours) / SUM(T.Hours) AS PercentComplete
FROM Projects AS P INNER JOIN
        Tasks AS T ON T.ProjectID = P.ProjectID
WHERE     (P.ProjectID = 1)

我的问题是关于该声明的这一部分:

SUM(T.PercentComplete * T.Hours) / SUM(T.Hours) AS PercentComplete

这给了我这个项目的正确加权百分比(在上面的样本数据的情况下,66%)。但我似乎无法理解为什么会这样做。

为什么此查询有效?

5 个答案:

答案 0 :(得分:4)

  • SUM(T.PercentComplete * T.Hours) / 100是完整小时数。
  • SUM(T.Hours)是总小时数。
  • 这两个数量的比例,即:

    (SUM(T.PercentComplete * T.Hours) / 100) / SUM(T.Hours)
    

    是完成小时的比例(应该在0和1之间)。

  • 将此乘以100得出百分比。

我更喜欢将这样的百分比保留在数据库之外并将它们移动到表示层。如果数据库存储“小时完成”和“小时总计”并且根本不存储百分比,则会容易得多。计算中100的额外因素混淆了这个问题。

答案 1 :(得分:2)

基本上,您可以在总小时数内找到完成的小时数。

SUM(T.PercentComplete * T.Hours)计算您完成的总小时数。 (100 * 50) = 50 * 100 + (120 * 80) = 146 * 100是分子。这项工作已完成146小时,我们保留了100倍数(因为它是[0-100]而不是[0-1]

然后我们找到工作小时数SUM(T.Hours),即100 + 120 = 220

然后划分,我们找到加权平均值。 (146 * 100) / 220 = 0.663636364 * 100 = 66.4%

这是你想知道的吗?

答案 2 :(得分:1)

它通过将每行的值相加然后在末尾将它们分开来单独计算两个总和

SUM(T.PercentComplete * T.Hours)

50*  100 +
80 * 120
-------
14,600

SUM(T.Hours)

100 +
120
---
220

然后是最后的分工

14,600 / 220
------------
66.3636

编辑根据HLGEM的评论,由于整数除法,它实际上会返回66.

答案 3 :(得分:0)

聚合函数(如SUM())可以处理GROUP BY子句定义的数据集。因此,如果按ProjectID,ProjectName进行分组,那么函数将会破坏它。

答案 4 :(得分:0)

SUM peratiorn首先乘以列而不是添加

( 100* 50+ 120* 80)  / (100+ 120)