MySQL - 更新当前行与上一行之间的列差异的行

时间:2011-10-24 23:30:15

标签: mysql

我有一个表data_temp,结构如下:

CREATE TABLE `data_temp` (
  `id` bigint(20) NOT NULL,
  `deviceid` int(11) NOT NULL,
  `registeraddress` int(11) NOT NULL,
  `value` decimal(20,9) NOT NULL,
  `time` datetime NOT NULL,
  `value_diff` decimal(20,9) NOT NULL DEFAULT '0.000000000',
  `time_diff` bigint(20) NOT NULL DEFAULT '0'
)

id是唯一但不连续的 记录对于deviceid / registeraddress / time是唯一的 插入的记录包含id,deviceid,registeraddress,值和时间的值 我想计算value_diff和time_diff,它们是插入记录与对应于deviceid和registeraddress的前一条记录之间的值差异,以秒为单位的时间差。

该表已经有很多记录,没有计算value_diff和time_diff所以我想用这些值更新表中的现有数据。

以下是一些示例数据:

id,  deviceid, registeraddress, value,time    
11102116190949258, 101, 856, 34.000000000, 2011-10-21 16:19:00
11102116240432553, 101, 856, 38.000000000, 2011-10-21 16:24:00
11102116290249672, 101, 856, 44.000000000, 2011-10-21 16:29:00
11102116340121243, 101, 856, 54.000000000, 2011-10-21 16:34:00
11102116390025291, 101, 856, 57.000000000, 2011-10-21 16:39:00
11102116440032519, 101, 856, 63.000000000, 2011-10-21 16:44:00

我可以在表格上进行以下选择,列出我想要的数据:

SELECT 
    r_B.deviceid, 
    r_B.registeraddress,
    r_B.value,
    r_B.time, 
    COALESCE(TIME_TO_SEC(TIMEDIFF(r_B.time,r_A.time)), 0) AS time_diff,
    COALESCE(r_B.value-r_A.value, 0) AS value_diff
FROM data_temp r_B
    LEFT OUTER JOIN data_temp r_A
    ON r_B.deviceid = r_A.deviceid 
        AND r_B.registeraddress = r_A.registeraddress 
        AND r_B.time > r_A.time
WHERE NOT EXISTS 
    (
        SELECT r_C.time 
        FROM data_temp r_C
        WHERE r_C.deviceid = r_C.deviceid 
            AND r_C.registeraddress = r_C.registeraddress 
            AND r_C.time > r_A.time 
            AND r_C.time < r_B.time
    )
ORDER BY r_B.deviceid, r_B.registeraddress, r_B.time

结果:

id,  deviceid, registeraddress, value, time, value_diff, time_diff
11102116190949258, 101, 856, 34.000000000, 2011-10-21 16:19:00, 0,   0.000000000
11102116240432553, 101, 856, 38.000000000, 2011-10-21 16:24:00, 300, 4.000000000
11102116290249672, 101, 856, 44.000000000, 2011-10-21 16:29:00, 300, 6.000000000
11102116340121243, 101, 856, 54.000000000, 2011-10-21 16:34:00, 300, 10.000000000
11102116390025291, 101, 856, 57.000000000, 2011-10-21 16:39:00, 300, 3.000000000
11102116440032519, 101, 856, 63.000000000, 2011-10-21 16:44:00, 300, 6.000000000

我现在已经尝试了几天来研究如何编写相应的更新。我尝试过以下方法:

UPDATE data_temp r_B
    LEFT OUTER JOIN data_temp r_A
    ON r_B.deviceid = r_A.deviceid 
        AND r_B.registeraddress=r_A.registeraddress 
        AND r_B.time > r_A.time
SET r_B.time_diff = COALESCE(TIME_TO_SEC(TIMEDIFF(r_B.time,r_A.time)), 0),
    r_B.value_diff = COALESCE(r_B.value-r_A.value, 0)
WHERE NOT EXISTS 
    (
        SELECT r_C.time 
        FROM data_temp r_C 
        WHERE r_C.deviceid = r_B.deviceid 
            AND r_C.registeraddress = r_B.registeraddress 
            AND r_C.time > r_A.time 
            AND r_C.time < r_B.time
    )

但当然会得到一个令人沮丧的MySQL错误:

Error Code: 1093
You can't specify target table 'r_B' for update in FROM clause

这里的问题是最后的WHERE子句。更新在没有子句的情况下工作但是给出了错误的结果(所有记录都使用当前记录和最旧记录之间的差异进行更新而不是之前的记录)。除WHERE子句外,语句中的其他所有内容都有效。

我一直在研究这个问题已经有一段时间没有找到一个好的解决方案,所以任何帮助都会受到赞赏。

0 个答案:

没有答案