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)