SQL AVG()函数返回不正确的值

5

我想在SQL中使用AVG函数来返回一些值的工作平均值(即基于上周而不是整体平均值)。 我正在计算两个值,weightrestingHR(心率)。 我对每个值都有以下SQL语句:

SELECT AVG( weight ) AS average 
FROM   stats 
WHERE  userid='$userid' 
ORDER BY date DESC LIMIT 7

SELECT AVG( restingHR ) AS average 
FROM   stats 
WHERE  userid='$userid' 
ORDER BY date DESC LIMIT 7

我得到的weight值为82.56,但应该是83.35。虽然这不是一个很大的误差,在使用时我会四舍五入,所以问题不太大。
然而,对于restingHR,我得到了45.96,而它应该是57.57,这是一个很大的差别。
我不明白为什么会出现这么大的偏差。非常感谢您的帮助。
谢谢。

你是怎么知道值应该是83.35的?能否请你发布一下你正在使用的数据? - RB.
您确定所使用的列不包含NULL值吗? - Oded
这里的 order bylimit 是什么意思? - Michael Krelin - hacker
将此查询的结果粘贴并让我们查看您的数据 SELECT weight AS average FROM stats WHERE userid='$userid' ORDER BY date DESC LIMIT 7 - codingbiz
你可以尝试使用between进行过滤,而不是使用order by:WHERE userid='$userid' and date BETWEEN '01/11/2012' and '09/11/2012'... - fabricio
2个回答

12

使用子查询来分离选择行和计算平均值:

SELECT AVG(weight) average
FROM (SELECT weight
      FROM stats
      WHERE userid = '$userid'
      ORDER BY date DESC
      LIMIT 7) subq

3
为了补充这个回答,因为它没有明确说明为什么需要这样做:LIMIT 7限制了输出的行数。当你进行聚合时,提供给聚合函数的记录数量不受影响。例如,SELECT x, AVG(y) FROM z GROUP BY x ORDER BY x LIMIT 7将返回7个不同的x值的结果,但每一行可能是一百万行的聚合结果。在你的情况下,你想限制被聚合的行数。通过使用子查询,你可以使用LIMIT选择只有7行,然后使用外部查询进行聚合。 - MatBailie
谢谢,这个完美地解决了问题。 我需要提高我的SQL知识,但我只学习了我所需的东西。直到现在大多数都是简单的东西。 - Henry Ing-Simmons
1
需要记住的重要事情是LIMIT和ORDER BY作用于结果,正如tombom所说。按照你的写法,它的意思是“返回最多7行平均值”,而不是“返回最多7行的平均值”。 - Barmar

2

看起来你想用ORDER BY date DESC LIMIT 7来筛选数据,但你必须考虑到ORDER BY子句在所有其他操作执行完成之后才会生效。因此,你的AVG()函数会考虑来自$userId的所有restingHR值,而不仅仅是最近的7个。

为了解决这个问题...好吧,Barmar刚刚发布了一个查询。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接