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

MariaDB/MySQL创建基于前20行求和的存储生成列报错求助

解决solar_generation表添加滚动总和列的方案

由于存储生成列不允许使用子查询或复杂聚合逻辑,直接通过ALTER TABLE创建目标存储生成列的方法不可行,以下是几种实用替代方案:

方案1:创建含滚动总和的视图

视图无需物理存储数据,可直接通过窗口函数计算当前行及前19行的总和,适合Home Assistant直接查询以简化逻辑。

假设表中有用于排序的时间戳列(如timestamp),执行以下SQL创建视图:

CREATE VIEW solar_generation_with_running_total AS
SELECT 
    *,
    SUM(amount) OVER(
        ORDER BY timestamp 
        ROWS BETWEEN 19 PRECEDING AND CURRENT ROW
    ) AS running_total
FROM solar_generation;

后续在Home Assistant中直接查询该视图即可,每次查询都会实时计算最新的滚动总和,无需额外维护。

方案2:用触发器维护普通列

若需要将滚动总和物理存储在表中,可先添加普通列,再通过触发器自动维护该列的值:

  1. 先添加普通列:
ALTER TABLE solar_generation ADD COLUMN running_total DECIMAL(10,2);
  1. 创建触发器(以MySQL 8.0+为例),在数据插入、更新或删除时自动更新受影响行的滚动总和:
DELIMITER //
CREATE TRIGGER update_running_total_after_insert AFTER INSERT ON solar_generation
FOR EACH ROW
BEGIN
    UPDATE solar_generation s
    JOIN (
        SELECT 
            id, -- 假设表中有主键id
            SUM(amount) OVER(
                ORDER BY timestamp 
                ROWS BETWEEN 19 PRECEDING AND CURRENT ROW
            ) AS new_total
        FROM solar_generation
    ) t ON s.id = t.id
    SET s.running_total = t.new_total
    WHERE s.id >= NEW.id - 19 AND s.id <= NEW.id;
END //
DELIMITER ;

注意:需根据实际表结构调整主键、时间列等字段,同时需额外创建UPDATE和DELETE触发器覆盖所有数据变更场景。此方案会增加写入时的性能开销,适合数据量不大的场景。

方案3:使用物化视图(PostgreSQL专属)

若使用PostgreSQL 12及以上版本,可创建物化视图定期刷新,兼顾物理存储的查询性能和数据的相对新鲜度:

  1. 创建物化视图:
CREATE MATERIALIZED VIEW solar_generation_mv AS
SELECT 
    *,
    SUM(amount) OVER(
        ORDER BY timestamp 
        ROWS BETWEEN 19 PRECEDING AND CURRENT ROW
    ) AS running_total
FROM solar_generation;
  1. 定期刷新物化视图以更新数据:
REFRESH MATERIALIZED VIEW solar_generation_mv;

可通过定时任务(如PostgreSQL的pg_cron插件)自动执行刷新,适合太阳能数据按固定间隔插入、对实时性要求不高的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 01:28:31