MS SQL - AVG()返回与AVG不同的结果(带组的AVG())

时间:2013-10-28 19:36:11

标签: sql sql-server aggregate-functions average

我正在摆弄MS SQL,在运行这两个查询后,我得到了不同的结果(...也许这只是我在MS SQL中的业余爱好):

/ *如果你发现任何语法错误无关紧要,我写的就是我的想法* /


SELECT 
    AVG(X.AvgDailyExpense) AS AverageDailyExpense
FROM
    (SELECT
        AVG(we.DailyExpense) AS AvgDailyExpense
    FROM
        WorkerExpense we
        LEFT JOIN Worker w ON w.Id = we.WorkerId 
    GROUP BY
        w.Id) X;

SELECT
    AVG(we.DailyExpense) AS AverageDailyExpense
FROM
    WorkerExpense we
    LEFT JOIN Worker w ON w.Id = we.WorkerId;

WorkerExpense和Worker之间有一个外键,WorkerExpense表不可能引用不存在的worker行。 另外,DailyExpense是货币数据类型(可能重要吗?)。

现在,较低的查询返回应该是正确的结果(我在少量行上手动计算结果),而上层查询总是返回一个大于它应该的值。

有谁能请更详细地解释一下为什么会发生这种情况?是因为数字四舍五入还是......?

3 个答案:

答案 0 :(得分:1)

这些查询将返回不同的结果,因为它们正在回答不同的问题。第二个查询回答“所有日常费用报告中的平均每日费用是多少”。第一个查询首先查找个人的平均每日费用,然后询问“基于个人的平均每日费用的平均值是多少”。他们正在回答非常不同的问题。

考虑它的另一种方式是第二个查询对具有大量费用报告的个人给予更大的权重。第一个查询按个人规范化数据。

答案 1 :(得分:1)

假设您的工人有以下费用:

A: 1, 2, 3, 4, 5, 6, 7, 8, 9   (average 45 / 9 = 5)
B: 12, 13, 14    (average 39 / 3 = 13)

所有费用的直接平均值为(45 + 39)/ 12 = 7,但两名工人的平均值为(5 + 13)/ 2 = 9。

答案 2 :(得分:1)

这是两个不同的数学问题。考虑一个具有两个WorkerExpense条目的Worker组,分别为0和3000.考虑具有单个WorkerExpense条目的第二个Worker组,即0。

您的第一个查询将首先查找两个组的平均值,例如1500和0,然后对这些数字求平均值,结果为750.

您的第二个查询将平均三个数字0,3000和0,结果为1000。

这是两件不同的事情。你必须决定你想要哪一个。