2010-07-20 63 views
0

我有一个表:如何在不使用python或php的情况下计算累计值?

  • LOCATION_ID(location) - 范围为0-90,000
  • 时间(time_period) - 1-15范围为每个位置
  • 温度(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); 

这是做到这一点的最有效的方式,也可以提出更好的东西?

+0

只是好奇,但到底是什么温度的总和是什么意思?是只计算平均值吗?我想不出有什么好的理由,但我确信我只是心胸狭隘。 – MJB 2010-07-20 02:00:44

+0

这是特定站点在特定时间内的总体温度。因此,如果我总结时间1到10的所有温度值,则在时间10时,该特定位置点经历了等于该总和的累积温度。我在雪融化和植物生长的情况下使用它。 我没有用它来计算平均值。 – Maiasaura 2010-07-21 02:07:03

回答

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

相关问题