有一个名为meterreadings
的表格。我需要将属性meterreading
从一行复制到另一行。
以下是数据样本:
id | meterreadingdate | meterreading | meterreadingtype_id | created
-------------------------------------------------------------------------------
1 | 2011-10-01 | 0 | 1 | 2011-10-15
2 | 2011-10-01 | 500 | 2 | 2011-10-15
基本上,我想根据meterreading
列复制所有meterreadingtype_id
值,以便将meterreadingtype_id
值2复制到1。
完成后数据应如下所示:
id | meterreadingdate | meterreading | meterreadingtype_id | created
-------------------------------------------------------------------------------
1 | 2011-10-01 | 500 | 1 | 2011-10-15
2 | 2011-10-01 | 500 | 2 | 2011-10-15
注意我复制了500,因为meterreadingtype_id
是1,我从下一行开始,因为它是2。
以下是我正在使用的查询:
update meterreadings mr1
set meterreading =
(
select
meterreading
from meterreadings
where
meterreadingtype_id = 2
and meterreadingdate = mr1.meterreadingdate
and location_id = mr1.location_id
and created = mr1.created
and asset_id = mr1.asset_id
)
where asset_id in (select id from assets where model_id in (select id from models where make_id IN (81, 82)))
and meterreadingtype_id = 1
如果有帮助,我们正在使用MySQL 5和InnoDB表。
答案 0 :(得分:1)
查询失败,因为您无法修改表并从子查询中的同一个表中进行选择。
一个限制是子查询的外部语句必须是以下之一:SELECT,INSERT,UPDATE,DELETE,SET或DO。另一个限制是,目前您无法修改表并从子查询中的同一个表中进行选择。这适用于DELETE,INSERT,REPLACE,UPDATE等语句(因为子查询可以在SET子句中使用)LOAD DATA INFILE。
我认为你可以用一些JOIN技巧解决这个问题:
UPDATE meterreadings AS tgt
INNER JOIN (
SELECT * FROM meterreadings
WHERE meterreadingtype_id = 2
) AS src
ON tgt.meterreadingdate = src.meterreadingdate
AND tgt.location_id = src.location_id
AND tgt.created = src.created
AND tgt.asset_id = src.asset_id
SET tgt.meterreading = src.meterreading
我不是MySQL专家,但我相信这是有效的,因为MySQL首先处理子查询并将结果作为临时表存储在内存中,在UPDATE期间不会更改。这样做的一个副作用是,如果子查询的结果很大,那么你就会嚼掉大量(或耗尽)内存。
解决内存问题的唯一方法(据我所知)是使用与更新目标没有直接关系的条件来削减子查询。例如,如果您要在夜间进程中执行这些更新,请使内部SELECT仅返回在过去~24小时内创建的行。