我在新行上每隔10秒就有一张带风向的表格(以及其他天气值).
方向存储为度数:0 – 360.
目的
这个平均值是什么意思?数据库每隔10秒存储一行信息.对于性能问题,我想将5天之前的数据汇总到每小时一(平均)线.
随着温度很容易实现:avg(temp)可以解决问题,因为温度不会在很多不同的值之间跳跃.
随着盛行风,获得这种“平均”要困难得多.
以度为单位计算平均风向并不像使用聚合函数avg()那样简单,因为它是一个圆,例如:
dir1 = 10; dir2 = 350;
avg() = (10+350)/2 = 180;
哪个不准确;它应该是:0或360.
因此,在我的脑海中,我的大学三角学课程认为,如果我将其转换为Radians,并计算x和y分量,我将能够重新计算平均方向.
while($w = $stmt->fetch()){
$x += cos(deg2rad($w['w']));
$y += sin(deg2rad($w['w']));
}
$angle = atan2($y,$x);
$angle = 360 + round(rad2deg($angle));
这个公式是否正确?
如果这个公式是正确的;理想情况下,我想获得MysqL的完整功能.我是这样做的;但我发现很多()的……
(360 + degrees(atan2(sum(sin(radians(W))),sum(cos(radians(W))))))) AS angle
最佳答案
初始建议的问题是它总是增加360,而如果atan2给出负面结果,你真的只想添加360.这可以用IF语句排序,但它比原始语言更笨重!
IF( degrees (atan2( sum(sin(radians(WindDirection))),sum(cos(radians(WindDirection))) ) )<0,360+degrees ( atan2( sum(sin(radians(WindDirection))),sum(cos(radians(WindDirection))) )),degrees(atan2(sum(sin(radians(WindDirection))),sum(cos(radians(MastDirection))) )) ) AS angle
我管理的最佳解决方案实际上使用了一个存储函数,如果您拥有数据库的权限,则可以创建该函数,如下所示:
CREATE FUNCTION Vavg (sumsindir FLOAT,sumcosdir FLOAT)
RETURNS FLOAT DETERMINISTIC
RETURN IF( DEGREES(atan2(sumsindir,sumcosdir))<0,360+DEGREES(atan2(sumsindir,sumcosdir)),DEGREES(atan2(sumsindir,sumcosdir)))
SELECT VavgTest( sum(sin(radians(WindDirection))),sum(cos(radians(WindDirection))) ) AS vectorAverage FROM table GROUP BY HOUR(MyTimestamp),DAYOFYEAR(MyTimestamp),YEAR(MyTimestamp)
ORDER BY MyTimestamp;
我已经将该组包括在内,以指出平均程序适用于任何平均周期.