遇到的错误是因为在 MySQL 中,你不能在 UPDATE 语句的 FROM 子查询中引用同一张表。在这种情况下,tpm_maintain_plan 既是目标表,也是子查询中的表,这样会导致错误。
解决方法:
可以通过使用 JOIN 代替子查询,或者通过 临时表 的方式来避免该错误。下面提供两种解决方案。
方案 1:使用 JOIN(避免子查询)
通过 JOIN 语法来代替子查询,直接在 UPDATE 语句中进行连接,避免了同一张表在 UPDATE 和 FROM 子查询中重复出现的问题。
UPDATE tpm_maintain_plan plan
JOIN tpm_maintain_record record
ON plan.id = record.plan_id
SET plan.status = '1'
WHERE plan.plan_code LIKE CONCAT('BY', '2025', '%')
AND plan.plan_time = 1;
解释:
- JOIN:在 UPDATE 语句中直接连接 tpm_maintain_plan 和 tpm_maintain_record,确保只有那些在 tpm_maintain_record 表中有记录的 plan_id 会被更新。
- WHERE:限定了 plan_code 以 ‘BY2025’ 开头,且 plan_time 为 1 的记录。
方案 2:使用临时表(如果表中数据量较大时)
如果你希望保留子查询的结构,可以通过将子查询的结果先存入临时表,再通过临时表进行更新。以下是一个示例:
- 创建临时表存储符合条件的 plan_id。
CREATE TEMPORARY TABLE temp_plan_ids AS
SELECT plan_id
FROM tpm_maintain_plan plan
JOIN tpm_maintain_record record
ON plan.id = record.plan_id
WHERE plan.plan_code LIKE CONCAT('BY', '2025', '%')
AND plan.plan_time = 1;
- 然后通过临时表来更新目标表。
UPDATE tpm_maintain_plan
SET status = '1'
WHERE id IN (SELECT plan_id FROM temp_plan_ids);
- 最后,删除临时表(如果不再需要)。
DROP TEMPORARY TABLE temp_plan_ids;
解释:
- 临时表:首先创建一个临时表 temp_plan_ids,将符合条件的 plan_id 存储进去。
- UPDATE:使用临时表中的 plan_id 来更新 tpm_maintain_plan 表。删除临时表:更新完成后,删除临时表以释放资源。
总结:
- 方案 1:推荐使用 JOIN 语法,它更简洁且避免了使用临时表。它的执行效率较高,适用于大多数场景。
- 方案2:如果有特殊需求或者数据量特别大,可以使用临时表。