最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
SQL中嵌套子查询能否直接作为更新源
时间:2026-07-16 08:19:47 编辑:袖梨 来源:一聚教程网
MySQL报ERROR 1093是引擎层对同一表既读又写的硬性限制,非语法错误;唯一安全绕过方式是将子查询包装为带别名的派生表(如SELECT ... FROM (SELECT ... FROM t) AS tmp),或改用UPDATE JOIN语法。
能,但只限于返回单行单列的标量子查询;多行、多列、或引用被更新表本身都会报错。
MySQL 里写 UPDATE ... SET col = (SELECT ...) 为什么报 ERROR 1093?
这是 MySQL 对“同一张表既查又改”的硬性限制,不是语法错,而是引擎层拦截。哪怕子查询只是读取本表某字段做判断,只要出现在 FROM 或显式关联中,就会触发。
- 唯一绕过方式是让子查询不显式出现被更新表名:用
WHERE c.id = orders.customer_id这种外层字段隐式引用,而不是FROM orders o2 - 如果子查询里真要查
orders表(比如找每个用户的最新订单时间),必须包装成派生表:SELECT * FROM (SELECT ...) AS tmp - 别指望加
LIMIT 1就能糊弄过去——ERROR 1093 在解析阶段就抛出,根本不会执行到 LIMIT
PostgreSQL / SQL Server 中 UPDATE ... FROM 和子查询的关系
它们支持 UPDATE ... FROM 语法,但子查询仍不能随意嵌套:若子查询含 GROUP BY、窗口函数或外部引用,仍可能报 “correlated subquery not allowed here”。
- PostgreSQL 允许
UPDATE t SET a = s.x FROM (SELECT ...) s WHERE t.id = s.id,但若子查询里写WHERE s.ref = t.id(即反向引用主表),会失败 - SQL Server 的
UPDATE t SET ... FROM t JOIN (SELECT ...) s ON ...更灵活,但必须确保子查询结果对主表每行最多匹配一次,否则最后一条覆盖前序更新,结果不可控 - 所有数据库都要求子查询结果集在 JOIN 条件下与目标表一对一映射,否则语义模糊
SET (c1, c2) = (SELECT a, b ...) 这种多列赋值到底能不能用?
MySQL 8.0.19+ 支持,但生产环境慎用——它表面简洁,实则脆弱。
- 子查询必须严格返回一行两列,且
SELECT列表里不能出现外层表字段(如orders.id),否则直接报错 - 没有索引支撑时,性能比等价的
JOIN差;出错提示也模糊,比如只报Operand should contain 1 column(s),实际可能是行数超限 - PostgreSQL 原生支持,SQL Server 完全不认这种写法,跨库迁移时必然断裂
- 真正稳的做法仍是
UPDATE t1 JOIN (SELECT ...) s ON t1.id = s.id SET t1.a = s.a, t1.b = s.b
最易被忽略的点:子查询是否返回 NULL,直接影响更新结果。没加 WHERE EXISTS 或 COALESCE 包裹时,匹配不到就设为 NULL,而不是跳过——这往往比语法报错更难排查。
相关文章
- 王者荣耀世界零氪玩家如何生存 07-28
- 快手极速版怎么绑定手机号 07-28
- 明日方舟和轻松小熊联动活动内容一览 07-28
- 逆战未来黎明之光 逆战未来黎明之光玩法机制与新手入门指南 07-28
- 植物大战僵尸融合版毁灭土豆地雷介绍 07-28
- 逆战未来飓风之龙 逆战未来飓风之龙武器获取方法详解 07-28