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 和 time 的值。
我想计算 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 子句之外,语句中的其他所有内容都有效。
我已经研究这个问题很长一段时间了,但还没有找到好的解决方案,因此我们将不胜感激。
I have a table data_temp with the following structure:
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 is unique but not contiguous.
Records are unique for deviceid/registeraddress/time.
Records are inserted which contain values for id,deviceid,registeraddress,value and time.
I want to calculate value_diff and time_diff which are the difference in value between the inserted record and the previous record corresponding to deviceid and registeraddress and difference in time in seconds.
The table already has a lot of records all without the value_diff and time_diff calculated so I want to update the existing data in the table with these values.
Here is some sample data:
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
I can do the following select on the table which will list the data that I want:
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
result:
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
I have been trying for a couple of days now to work out how to write the corresponding update. I have tried the following:
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
)
But of course get the slightly frustrating MySQL error:
Error Code: 1093
You can't specify target table 'r_B' for update in FROM clause
The problem here is with the WHERE clause at the end. The update works without the clause but gives the wrong result (all records are updated with the difference between the current and the oldest record not the previous record). Everything else in the statement works except the WHERE clause.
I have been researching this for quite a while now and haven't found a good solution so any help would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论