MySQL 中 DELETE 语句中可以使用别名么?
某天,正按照业务的要求删除不需要的数据,在执行 DELETE 语句时,竟然出现了报错!
作者:林靖华,开源数据库技术爱好者,擅长MySQL和Redis的运维
爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
本文约 650 字,预计阅读需要 2 分钟。
背景
某天,正按照业务的要求删除不需要的数据,在执行 DELETE 语句时,竟然出现了报错(MySQL 数据库版本 5.7.34):
mysql> delete from test1 t1 where not exists (select 1 from test2 t2 where t1.id=t2.id); ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't1 where not exists (select 1 from test2 t2 where t1.id=t2.id)' at line 1
这就有点奇怪了,因为我在执行删除语句之前,执行过同样条件的 SELECT 语句,只是把其中的 select *
换成了 delete
而已,毕竟这个语法的报错一般来说原因很大可能是 关键字拼写错误 或者 存在中文符号。
排除了上面的原因后,再从语句本身的逻辑来排查,难道说 DELETE 语句不支持 not exists
这种写法?好像之前也没听说过这个限制。我们还是以语法错误这个原因为起点,去查查官方文档看下能不能找出答案。
分析
DELETE 的语法如下:
5.7 单表删除格式
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name [PARTITION (partition_name [, partition_name] ...)] [WHERE where_condition] [ORDER BY ...] [LIMIT row_count]
仔细对比了以下,发现了一些端倪,这里的语法并没有写出表名的别名用法,难道是使用了别名的原因?
mysql> delete from test1 where not exists (select 1 from test2 where test1.id=test2.id); Query OK, 1 row affected (0.00 sec)
经测试去掉了别名还真的执行成功了,但我印象中之前删除数据的时候用过别名,于是我再继续深挖文档查查看。
对比不同地方和不同版本的格式差异后,我终于明白了问题的起因。在不同版本,甚至不同情况下都有差异。
8.0 单表删除格式
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name [[AS] tbl_alias] [PARTITION (partition_name [, partition_name] ...)] [WHERE where_condition] [ORDER BY ...] [LIMIT row_count]
5.7 和 8.0 多表删除格式
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] tbl_name[.*] [, tbl_name[.*]] ... FROM table_references [WHERE where_condition] DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name[.*] [, tbl_name[.*]] ... USING table_references [WHERE where_condition]
经过上面语法对比的不同发现,5.7 的单表删除确实不支持别名的使用,但是多表删除却支持(table_references
里包含别名的使用)。
并且在 8.0.16 开始,单表删除已经支持使用别名了。
For consistency with the SQL standard and other RDBMS, table aliases are now supported in single-table as well as multi-table DELETE statements. (Bug #27455809)
结论
- MySQL 5.7 使用单表删除语句时,不能使用别名,多表删除可以使用别名。
- MySQL 8.0.16 开始单表多表都可以使用别名。
更多技术文章,请访问:https://opensource.actionsky.com/
关于 SQLE
SQLE 是一款全方位的 SQL 质量管理平台,覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。
SQLE 获取

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
OpenNJet KIC v1.0发布!K8s Ingress Controller
NGINX 向云原生演进,All inOpenNJet概述 OpenNJet KIC(K ubernetes Ingress Controller)基于OpenNJet proxy的动态特性、高性能实现。弥补nginx 在云原生场景中应用的不足。提供了丰富的流量管理能力,如动态location、host/path路由、负载均衡、动态upstream、金丝雀发布、TLS Termination/SNI等。 本版本主要特性: 支持Ingress API、支持path/host路由 支持自定义资源VirtualServer,支持path/host、高级(header、请求方法等)路由 支持动态Upstream 支持Upstream 负载均衡, 支持round-robin 及 consitent hash 算法 支持Upstream 主动健康检查 支持 TLS SNI 支持Prometheus 指标采集 架构图如下: 新特性概览 Ingress API OpenNJet KIC采用动态API方式实现基本路由/TLS的变化的更改,当Ingress资源变化时,而不需要reload OpenNJe...
- 下一篇
【直播预告】替代 Oracle,我们还有多长的路要走?
早在十多年前,就有了 “去 IOE ” 的提议。2008 年,时任阿里巴巴首席架构师的王坚提议,减少外国供应商,并用内部开发的设备和技术取而代之。 所谓减少外国供应商,主要就是要摆脱 IOE 系统——服务器 IBM,数据库软件 Oracle,存储设备 EMC,三者构成了一个从软件到硬件的企业数据库系统,几乎占领了全球大部分商用数据库系统市场份额。 原本,“去 IOE ” 只是阿里为了节省成本的一场技术革新。IBM 小型机价格从几十万到高达百万级人民币,与 Oracle 签订的数据库软件费用达数千万,还要再加上一大笔软硬件支付和一大笔维护费,维持 IOE 的成本太过高昂。 在我国频频遭遇外国技术封锁之后,“去 IOE ” 成为了软件行业自主可控的正面战场之一。在信创的推波助澜之下,国产化替代更是势不可挡。Oracle 数据库作为 IOE 的核心系统,国产化替代的进程到底如何呢? 要知道,替代 Oracle 并不是一蹴而就的事情。Oracle 在数据库领域的地位是建立在多年的技术积累和市场认可之上的。替代 Oracle 需要考虑到企业的具体需求、现有系统的迁移成本以及新技术的可行性和稳定性...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS8编译安装MySQL8.0.19
- CentOS7设置SWAP分区,小内存服务器的救世主