DELETE
语法
单表语法:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name [PARTITION (partition_list)] [WHERE where_condition] [ORDER BY ...] [LIMIT row_count] [RETURNING select_expr [, select_expr ...]]
多表语法:
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]
Trimming history:
DELETE HISTORY FROM tbl_name [PARTITION (partition_list)] [BEFORE SYSTEM_TIME [TIMESTAMP|TRANSACTION] expression]
描述
选项 | 描述 |
---|---|
LOW_PRIORITY | DELETE延迟执行,直到没有其他客户端SELECT表。只有使用表锁的存储引擎(MyISAM、Aria等)才需要使用,详见HIGH_PRIORITY and LOW_PRIORITY clauses。 |
QUICK | 通知存储引擎它期望删除很多行。存储引擎收到这类通知后,会做出一些行为加速DELETE操作。例如DELETE执行过程中忽略数据块的合并,直到DELETE结束。这加快了数据块中空间丢失的扩散速度。至少MyISAM和Aria支持该特性。 |
IGNORE | 即使DELETE某行的过程中发生了错误,也继续向后执行DELETE操作。见How IGNORE works。 |
对于单表DELETE,DELETE
语句删除tbl_name
中的行,并返回成功删除的行数量。该数量可以通过ROW_COUNT()函数获取。如果给定了WHERE
子句,则筛选出哪些行需要删除。没有WHERE
子句时,会删除表中所有行。如果给定了ORDER BY子句,则数据会先排序,并按顺序删除。如果给定了LIMIT子句,则只删除一定数量的行。
对于多表DELETE,DELETE
语句删除tbl_name
中满足条件的行。这种情况下,不能使用ORDER BY和LIMIT子句。DELETE
可以通过db_name.tbl_name
(见Identifier Qualifiers)的方式引用不同数据库中的表,因此可以删除不同数据库中的数据。
where_condition
是一个表达式,用于评估筛选哪些行会被删除。
直到目前为止,还无法删除某表的同时在子查询中select该表数据。
要删除行,需要对表具有DELETE
权限,而对于那些只用来读取的字段,只需要对字段具有SELECT
权限即可,例如WHERE
中引用的字段。见GRANT。
MariaDB starting with 10.0
PARTITION子句是MariaDB 10.0中引入的特性。详细信息见Partition Pruning and Selection。
按照规定,没有给定WHERE
子句的DELETE
语句会删除表中的所有行。如果你不需要知道删除了多少行,那么可以使用更快的删除方式TRUNCATE TABLE
。但是,在事务中或者表上有锁的时候,TRUNCATE TABLE
无法执行,而DELETE
可以。见TRUNCATE TABLE
和
LOCK
。
MariaDB starting with 10.0.5
从MariaDB 10.0.5开始,可以为单表DELETE返回删除行相关的数据,只需使用DELETE ... RETURNING select_expr [, select_expr2 ...]]
语法即可。
/* 此为译注所给示例 */ /* 删除id>5的记录时,同时返回t1表中所有的字段 */ DELETE FROM t1 WHERE id>5 RETURNING *; +----+------+------+--------+ | id | comp | sex | number | +----+------+------+--------+ | 6 | A | nan | 60 | | 7 | A | nan | 60 | +----+------+------+--------+ /* 删除id<3的记录时,同时返回t1表中id+3的值 */ DELETE FROM t1 WHERE id<3 RETURNING id+3; +------+ | id+3 | +------+ | 4 | | 5 | +------+
多表删除不允许使用RETURNING。 SQL表达式可以从单行的字段中计算得出。允许使用子查询。允许使用AS关键字,因此可以使用别名。
不允许使用聚合函数。
MariaDB starting with 10.3.1
源和目标相同
MariaDB 10.3.1之前,无法删除源和目标相同的表。从MariaDB 10.3.1开始,允许删除源和目标相同的表。例如:
DELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);
MariaDB starting with 10.3.4
从MariaDB 10.3.4开始,可以使用DELETE HISTORY
删除System-versioned tables中的历史信息。
示例
DELETE FROM page_hit ORDER BY timestamp LIMIT 1000000;
如何使用RETURNING子句:
DELETE FROM t RETURNING f1; +------+ | f1 | +------+ | 5 | | 50 | | 500 | +------+
下面的语句联接了两张表:其中blog表用于匹配WHERE条件,该表中的数据不会被删除;post表中的数据会被删除。
DELETE post FROM blog INNER JOIN post WHERE blog.id = post.blog_id;
源和目标相同的DELETE
CREATE TABLE t1 (c1 INT, c2 INT); DELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);
MariaDB 10.3.1之前,该语句返回:
ERROR 1093 (HY000): Table 't1' is specified twice, both as a target for 'DELETE' and as a separate source for
Query OK, 0 rows affected (0.00 sec)