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_PRIORITYDELETE延迟执行,直到没有其他客户端SELECT表。只有使用表锁的存储引擎(MyISAM、Aria等)才需要使用,详见HIGH_PRIORITY and LOW_PRIORITY clauses
QUICK通知存储引擎它期望删除很多行。存储引擎收到这类通知后,会做出一些行为加速DELETE操作。例如DELETE执行过程中忽略数据块的合并,直到DELETE结束。这加快了数据块中空间丢失的扩散速度。至少MyISAMAria支持该特性。
IGNORE即使DELETE某行的过程中发生了错误,也继续向后执行DELETE操作。见How IGNORE works

对于单表DELETE,DELETE语句删除tbl_name中的行,并返回成功删除的行数量。该数量可以通过ROW_COUNT()函数获取。如果给定了WHERE子句,则筛选出哪些行需要删除。没有WHERE子句时,会删除表中所有行。如果给定了ORDER BY子句,则数据会先排序,并按顺序删除。如果给定了LIMIT子句,则只删除一定数量的行。

对于多表DELETE,DELETE语句删除tbl_name中满足条件的行。这种情况下,不能使用ORDER BYLIMIT子句。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 TABLELOCK

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中的历史信息。

示例

如何使用ORDER BYLIMIT子句:

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

MariaDB 10.3.1之后:

Query OK, 0 rows affected (0.00 sec)

See also

Comments

Comments loading...
Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.