【问题标题】:Different results returned between SUM()/total rows and AVG() in sql serversql server 中的 SUM()/total rows 和 AVG() 之间返回的结果不同
【发布时间】:2014-10-19 23:36:01
【问题描述】:

我有一个 #time_per_bike 表,有 6549 行(不存在重复项。即使是 bikeid 列也有唯一的 ID)。请查看示例 -

谁能告诉我为什么我在两个查询之间得到不同的结果(因为我相信他们执行相同的操作。如果我错了,请纠正我)?

select SUM(AVG_WAIT_TIME)/6549 from #time_per_bike
-- Returns 69499

select AVG(AVG_WAIT_TIME) from #time_per_bike
-- Returns 69520

【问题讨论】:

    标签: sql sql-server sql-server-2008 sum average


    【解决方案1】:

    "除 COUNT(*) 函数外,所有聚合函数都执行一个 Null 消除步骤,因此 Null 值不包含在 计算的最终结果。”参考:http://en.wikipedia.org/wiki/Null_(SQL)

    所以你的数据中有一些NULLs。

    您有两种选择,具体取决于您希望如何处理数据中的空值。您可以将其视为零值,也可以完全消除这些行,以免它们对 COUNT(*) 产生影响(就像 AVG() 所做的那样)。

    来自引用的 wiki 页面:

    例如,在下表中,AVG(i)(值的平均值 i) 的结果与 AVG(j) 的结果不同:

    Table
    i         j
    150     150
    200     200
    250     250
    NULL      0
    

    这里 AVG(i) 是 200(150、200 和 250 的平均值),而 AVG(j) 是 150(150、200、250 和 0 的平均值)。

    众所周知的副作用 这就是在 SQL 中 AVG(z) 不等于 SUM(z)/COUNT(*)

    【讨论】:

    • 你是对的@Mitch。我有两个带有 NULLS 的 AVG_WAIT_TIME。那么在这种情况下,哪个是正确的平均值?我猜是 AVG()
    • 嗯,这完全取决于您希望如何处理数据中的空值。您可以将其视为零值,也可以完全消除这些行(这样它们就不会影响 COUNT(*))
    • 谢谢,我最好用 0 更新这两个空值并取平均值。
    • 与其更新行,不如使用 CASE 语句创建视图以将 NULL 转换为零
    • 非常感谢@Mitch 从#time_per_bike 中选择 AVG(当 AVG_WAIT_TIME 为 NULL 时为 0,否则为 0,否则为 AVG_WAIT_TIME 结束)
    猜你喜欢
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多