MySql表自修改报错:You can‘t specify target table ‘student‘ for update in FROM clause

文章目录

一、发现问题

在一次准备处理历史数据sql时,出现这么一个问题:You can't specify target table '表名' for update in FROM clause,大致的意思就是:不能在同一张表中先select再update。

在此进行一下复盘沉淀,使用测试sql复现当时的场景(mysql是8版本),准备测试数据:

sql 复制代码
CREATE TABLE `student` (
  `id` int NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `athena_opencourse`.`student`(`id`, `name`, `address`) VALUES (1, '张三', '北京');
INSERT INTO `athena_opencourse`.`student`(`id`, `name`, `address`) VALUES (2, '李四', '上海');

二、场景1:在where条件中查询了修改表的数据

sql 复制代码
update student set address = '杭州'
where id in (select id from student where name = '张三');

delete from  student
where id in (select id from student where name = '张三');

此时会提示:1093 - You can't specify target table 'student' for update in FROM clause

解决方式:在where子句中再加一层,使其成为临时表:

sql 复制代码
update student set address = '杭州'
where id in (select tmp.id from (select id from student where name = '张三') tmp);

三、场景2:在set语句中查询了修改表的数据

sql 复制代码
update student set address = (select address from student where name = '李四')
where name = '张三';

此时,一样的报错:> 1093 - You can't specify target table 'student' for update in FROM clause

解决方式同上,查询时再加一层,使其成为临时表:

sql 复制代码
update student set address = (select tmp.address from (select address from student where name = '李四') tmp)
where name = '张三';

或者使用update join的方案:

sql 复制代码
update student s1 ,student s2 
set s1.address = s2.address
where s1.name = '张三' and s2.name = '李四';

惊呆了有木有!使用update join语法,可以很轻松的实现跨表的数据修改。

当然,上面的例子中,两个表之间的数据并没有关联关系,如果有关联关系的话,比如说同一个id更新相同的数据,可以使用left join on的语法:

sql 复制代码
update student s1 
left join student s2 on s1.id = s2.id
set s1.address = s2.name;
相关推荐
不羁。。1 小时前
【撸靶笔记】第七关:GET - Dump into outfile - String
数据库·笔记·oracle
yangchanghua1113 小时前
pgsql 如何查询今天范围内的数据(当天0点0分0秒 - 当天23点59分59秒....)
数据库·pgsql
larance3 小时前
SQLAlchemy 的异步操作来批量保存对象列表
数据库·python
python_chai3 小时前
从数据汇总到高级分析,SQL 查询进阶实战(下篇)—— 分组、子查询与窗口函数全攻略
数据库·sql·mysql
在努力的前端小白3 小时前
Spring Boot 敏感词过滤组件实现:基于DFA算法的高效敏感词检测与替换
java·数据库·spring boot·文本处理·敏感词过滤·dfa算法·组件开发
未来之窗软件服务3 小时前
自建知识库,向量数据库 (九)之 量化前奏分词服务——仙盟创梦IDE
数据库·仙盟创梦ide·东方仙盟·自建ai·ai分词
冒泡的肥皂7 小时前
MVCC初学demo(一
数据库·后端·mysql
.Shu.8 小时前
Redis Reactor 模型详解【基本架构、事件循环机制、结合源码详细追踪读写请求从客户端连接到命令执行的完整流程】
数据库·redis·架构
Bruce_Liuxiaowei10 小时前
MySQL完整重置密码流程(针对 macOS)
mysql
麦麦大数据10 小时前
F003疫情传染病数据可视化vue+flask+mysql
mysql·flask·vue·大屏·传染病