====================================================================
| name | serial_id | timestamp | cumulative | difference |
====================================================================
| X | AA01 | 2014-12-16 12:50:01 | 832 | |
| Y | AB02 | 2014-12-16 12:50:01 | 1526 | |
| X | AA01 | 2014-12-16 12:51:01 | 835 | 3 |
嗨大家好,MySQL新手再来一次,
前一段时间,我构建了一个这样的数据库,作为跟踪一堆系统的方法。这些系统具有计数器,该计数器是累积数。我想追溯更新MySQL表,并添加一个列,让我区分这些计数器,基本上,更新行并添加" 3"。这里有皱纹,表中没有唯一的ID键,但您可以考虑serial_id + timestamp a"复合键"。为了使用这样的计算更新整个大规模表,我需要什么SQL语句。
答案 0 :(得分:0)
获得结果的SQL语句是:
select t.*,
(t.cumulative -
(select t2.cumulative
from table t2
where t2.name = t.name
order by timestamp desc
limit 1
)
) as diff
from table t;
在MySQL中,您可以使用join
:
update table t join
(select t.*,
(t.cumulative -
(select t2.cumulative
from table t2
where t2.name = t.name
order by timestamp desc
limit 1
)
) as diff
from table t
) tt
on t.name = tt.name and t.timestamp = tt.timestamp
set t.difference = tt.diff
where tt.diff is not null;
使用变量的另一种方法有点麻烦但可能更快。这很棘手,因为您无法初始化查询中的变量,因此它们始终是字符串:
update table t
set t.difference = (t.cumulative -
(case when @n = name -- name doesn't change so use previous value
then (case when (@p := @prev) = NULL then 0 -- guaranteed to fail
when (@prev := cumulative) = NULL then 0 -- guaranteed to fail
else @p
end)
when (@n := name) = NULL then 0 -- guaranteed to fail
else NULL
end
)
order by t.name, t.timestamp
变量逻辑相当复杂 - 在MySQL中获取先前的值有点困难,因为所有逻辑都必须适合单个语句。 case
用于处理逻辑中的多个步骤。
此外,使用table(name, timestamp)
上的索引可以更好地工作。