在我的架构中,我有一个表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%)。但我似乎无法理解为什么会这样做。
为什么此查询有效?
答案 0 :(得分:4)
SUM(T.PercentComplete * T.Hours) / 100
是完整小时数。SUM(T.Hours)
是总小时数。这两个数量的比例,即:
(SUM(T.PercentComplete * T.Hours) / 100) / SUM(T.Hours)
是完成小时的比例(应该在0和1之间)。
我更喜欢将这样的百分比保留在数据库之外并将它们移动到表示层。如果数据库存储“小时完成”和“小时总计”并且根本不存储百分比,则会容易得多。计算中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)