You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建含移动平均线的计算列遇Error Code3593报错求助

解决MySQL创建移动平均线计算列报错的问题

错误原因

MySQL的**生成列(Generated Column)**不支持使用窗口函数(比如AVG() OVER()),这是语法层面的限制,所以直接通过ALTER TABLE添加包含窗口函数的计算列会触发Error Code: 3593。

另外注意:你原代码里ROWS BETWEEN 9 PRECEDING AND CURRENT ROW计算的是最近10条数据的平均值(MA10),如果要实现MA100,需要改成ROWS BETWEEN 99 PRECEDING AND CURRENT ROW。

解决方案

1. 创建视图(推荐,无需持久化数据)

如果不需要把MA100存储在表中,而是查询时动态获取,创建视图是最优方案:

CREATE VIEW ibstocks.stocks_with_ma AS
SELECT 
    *,
    CAST(AVG(close) OVER(PARTITION BY Symbol ORDER BY date ROWS BETWEEN 99 PRECEDING AND CURRENT ROW) AS DECIMAL(8,2)) AS MA100
FROM ibstocks.stocks;

使用时直接查询视图:SELECT * FROM ibstocks.stocks_with_ma;

2. 手动维护持久化列

如果必须把MA100存储在表中,可以通过触发器或定时任务来维护:

  • 第一步:添加普通列
ALTER TABLE ibstocks.stocks ADD COLUMN MA100 DECIMAL(8,2);
  • 第二步:创建触发器(插入/更新时自动更新MA100)
    假设表有主键id,如果没有可以用Symbol+date作为唯一关联键:
DELIMITER //
CREATE TRIGGER update_stock_ma100 AFTER INSERT ON ibstocks.stocks
FOR EACH ROW
BEGIN
    UPDATE ibstocks.stocks s
    JOIN (
        SELECT 
            id,
            CAST(AVG(close) OVER(PARTITION BY Symbol ORDER BY date ROWS BETWEEN 99 PRECEDING AND CURRENT ROW) AS DECIMAL(8,2)) AS new_ma100
        FROM ibstocks.stocks
        WHERE Symbol = NEW.Symbol
    ) ma ON s.id = ma.id
    SET s.MA100 = ma.new_ma100;
END //
DELIMITER ;

注意:如果数据量较大,触发器可能影响写入性能,此时建议用MySQL事件调度器定时批量更新MA100。

3. 查询时动态计算

如果只是偶尔需要MA100数据,直接在查询语句中计算即可:

SELECT 
    *,
    CAST(AVG(close) OVER(PARTITION BY Symbol ORDER BY date ROWS BETWEEN 99 PRECEDING AND CURRENT ROW) AS DECIMAL(8,2)) AS MA100
FROM ibstocks.stocks;

内容的提问来源于stack exchange,提问作者tomaskunes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 06:15:36