gpt4 book ai didi

MySQL计算N行的移动平均值

转载 作者:行者123 更新时间:2023-11-29 02:51:49 24 4
gpt4 key购买 nike

我正在尝试计算单个查询中 N 行的移动平均值, 所有行。在本示例中,我尝试计算 50 行的移动平均值。

SELECT 
h1.date,
h1.security_id,
( SELECT
AVG(last50.close)
FROM (
SELECT h.close
FROM history as h
WHERE h.date <= h1.date AND h.security_id = h1.security_id
ORDER BY h.date DESC
LIMIT 50
) as last50
) as avg50
FROM history as h1

但是,MySQL 在运行此查询时给我一个错误:

“where 子句”中的未知列“h1.date”

我正在尝试这种方法,因为列出的其他解决方案似乎并不真正适用于我的用例。有 N 的移动平均值的解决方案,但由于我的数据集中没有考虑所有日期,我需要 N 的平均值。

This solution ,如下所示,不起作用,因为 AVG(还有 SUMCOUNT)没有考虑 LIMIT :

SELECT
t1.data_date
( SELECT SUM(t2.price) / COUNT(t2.price)
FROM t as t2
WHERE t2.data_date <= t1.data_date
ORDER BY t2.data_date DESC
LIMIT 5
) AS 'five_row_moving_average_price'
FROM t AS t1
ORDER BY t1.data_date;

This question看起来很有前途,但对我来说有点难以理解。

有什么建议吗? Here's an SQLFiddle在里面玩耍。

最佳答案

计划

  • self join history on last 50 days
  • take average grouping by date and security id ( of current )

查询

select curr.date, curr.security_id, avg(prev.close)
from history curr
inner join history prev
on prev.`date` between date_sub(curr.`date`, interval 49 day) and curr.`date`
and curr.security_id = prev.security_id
group by 1, 2
order by 2, 1
;

输出

+---------------------------+-------------+--------------------+
| date | security_id | avg(prev.close) |
+---------------------------+-------------+--------------------+
| January, 04 2016 00:00:00 | 1 | 10.770000457763672 |
| January, 05 2016 00:00:00 | 1 | 10.800000190734863 |
| January, 06 2016 00:00:00 | 1 | 10.673333485921225 |
| January, 07 2016 00:00:00 | 1 | 10.59250020980835 |
| January, 08 2016 00:00:00 | 1 | 10.432000160217285 |
| January, 11 2016 00:00:00 | 1 | 10.40166680018107 |
| January, 12 2016 00:00:00 | 1 | 10.344285828726631 |
| January, 13 2016 00:00:00 | 1 | 10.297500133514404 |
| January, 14 2016 00:00:00 | 1 | 10.2877779006958 |
| January, 04 2016 00:00:00 | 2 | 56.15999984741211 |
| January, 05 2016 00:00:00 | 2 | 56.18499946594238 |
| .. | .. | .. |
+---------------------------+-------------+--------------------+

sqlfiddle

引用


修改为使用最后 50 行

select
rnk_curr.`date`, rnk_curr.security_id, avg(rnk_prev50.close)
from
(
select `date`, security_id,
@row_num := if(@lag = security_id, @row_num + 1,
if(@lag := security_id, 1, 1)) as row_num
from history
cross join ( select @row_num := 1, @lag := null ) params
order by security_id, `date`
) rnk_curr
inner join
(
select date, security_id, close,
@row_num := if(@lag = security_id, @row_num + 1,
if(@lag := security_id, 1, 1)) as row_num
from history
cross join ( select @row_num := 1, @lag := null ) params
order by security_id, `date`
) rnk_prev50
on rnk_curr.security_id = rnk_prev50.security_id
and rnk_prev50.row_num between rnk_curr.row_num - 49 and rnk_curr.row_num
group by 1,2
order by 2,1
;

sqlfiddle

注意

if 函数用于强制变量评估的正确顺序。

关于MySQL计算N行的移动平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34832942/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com