我有一张桌子:
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 :(得分: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”