如何在不使用python或php的情况下计算累积值?

时间:2010-07-20 00:06:47

标签: mysql

我有一张桌子:

  • location_id(location) - 范围为0-90,000
  • 时间(time_period) - 每个位置的范围为1-15
  • temperature(temp) - 每个位置的唯一值x time_period。

示例数据:

location time_period temp
91         1          -4
91         2          3
91         3          12
.......................
.......................
91         15         20

我想创建一个名为cum_temp的新字段,并为每个单元格添加累积值,直到当前time_period。我目前的想法是复制表并运行:

update site_a 
   set cum_temp = (select sum(temp) 
                     from site_a_copy 
                    where site_a_copy.location = site_a.location 
                      and site_a_copy.time_period <= site_a.time_period);

这是最有效的方法吗?或者你可以提出更好的建议吗?

1 个答案:

答案 0 :(得分:0)

请注意,您不需要单独的表,除非您不想将累积温度存储在其中一个表中。

定期或手动运行查询会有效(虽然可以从stored procedure执行),或者您可以尝试使用trigger自动执行此操作:

CREATE TRIGGER sum_temp
  BEFORE INSERT ON site
  FOR EACH ROW
    SET NEW.cum_temp = NEW.temp + (
        SELECT SUM(temp) FROM site 
          WHERE site.location_id = NEW.location_id
            AND site.`time` < NEW.`time`
      );

但是,此应用程序的触发器充满了危险。首先,上面的内容不会更新新行之后的任何行。只要您只追加新记录,这不是一个严重的问题。获取更新后续行的触发器基本上是不可能的,因为行级锁定会阻止您在INSERT和UPDATE触发器中向同一个表发出UPDATE。将累积温度存储在另一个表格中可以解决这个问题。

其次,当使用单个INSERT语句插入多个值时,新行必须在语句中按时间顺序排列,否则累积温度将设置不正确。在计算稍后但在INSERT中较早的行的累积温度时,将不会考虑早期但稍后在INSERT中的行。这是第一个问题的结果。

您还可以使用视图:

CREATE VIEW site_a AS
    SELECT *, SUM(temp) AS cum_temp
      FROM site AS s
      JOIN site AS t 
        ON s.location_id=t.location_id AND s.time_period >= t.time_period
;

另请参阅“UPDATE TABLE WITH SUM