DELETE — 删除一个表的行
[ WITH [ RECURSIVE ]with_query
[, ...] ] DELETE FROM [ ONLY ]table_name
[ * ] [ [ AS ]alias
] [ USINGfrom_item
[, ...] ] [ WHEREcondition
| WHERE CURRENT OFcursor_name
] [ ORDER BYexpression
[ ASC | DESC | USINGoperator
] [ NULLS { FIRST | LAST } ] [, ...] ] [ LIMIT {count
| ALL } ] [ OFFSETstart
[ ROW | ROWS ] ] [ RETURNING * |output_expression
[ [ AS ]output_name
] [, ...] ]
DELETE
从指定表中删除满足
WHERE
子句的行。如果WHERE
子句没有出现,效果将会是删除表中的所有行。结果是一个合法的空表。
TRUNCATE
提供移除表中所有行的快速机制。
有两种方式可以使用数据库中其他表中包含的信息来删除一个表的行:
使用子选择或者在USING
子句中指定额外的表。
哪种技术更合适取决于特定的环境。
可选的RETURNING
子句导致DELETE
基于实际被删除的每一行计算并且返回值。任何使用被删除表列或者
USING
中提到的其他表的列的表达式都可以被计算。
RETURNING
列表的语法和SELECT
的
输出列表语法相同。
要从表中删除行,你必须具有其上的DELETE
特权,
以及USING
子句中任何表以及其值在condition
中被读取的表上的
SELECT
特权。
如果指定了 ORDER BY
子句,可以按指定的顺序删除行。
它的语义类似于 SELECT
中的 ORDER BY
子句。
请注意,不支持带有 ORDER BY
子句的继承表删除,也不支持 Canopy。
如果指定了 LIMIT
或 OFFSET
子句,则可以删除行的子集。
它的语义类似于 SELECT
中的 LIMIT
子句。
请注意,不支持带有 LIMIT
或 OFFSET
子句的继承表更新,也不支持 Canopy。
with_query
WITH
子句允许你指定一个或者多个子查询,在
DELETE
查询中可以用子查询的名字来引用它们。
详见Section 8.8和SELECT。
table_name
要从其中删除行的表名(可以是模式限定的)。如果在表名前指定
ONLY
,只会从提到的表中删除匹配的行。如果没有指定
ONLY
,还会删除该表的任何继承表中的匹配行。可选地,
可以在表名后面指定*
来显式指定要包括继承表。
alias
目标表的一个别名。提供别名时,它会完全隐藏该表的真实名称。例如,
对于DELETE FROM foo AS f
,
DELETE
语句的剩余部分都会用
f
而不是 foo
来引用该表。
from_item
一个表的表达式允许在WHERE
条件中出现
来自其他表的列。这使用与SELECT
语法的
FROM
子句相同的语法;
例如,可以指定表名的别名。除非您希望建立自联接(在这种情况下,它必须与
from_item
中的别名一起出现),否则不要
将目标表重复为from_item
。
condition
一个返回boolean
类型值的表达式。只有让这个
表达式返回true
的行才将被删除。
cursor_name
要在WHERE CURRENT OF
情况中使用的游标
的名称。最近一次从这个游标中取出的行将被删除。该游标
必须是DELETE
的目标表上的非分组查询。
注意不能在使用WHERE CURRENT OF
的同时
指定一个布尔条件。有关将游标用于
WHERE CURRENT OF
的更多信息请见
DECLARE。
output_expression
在每一行被删除后,会被DELETE
计算并且返回的表达式。
该表达式可以使用table_name
以及USING
中的表的任何列。写成*
可以返回所有列。
output_name
被返回列的名称。
在成功完成时,一个DELETE
命令会返回以下形式
的命令标签:
DELETE count
count
是被删除行的数目。
注意如果有一个BEFORE DELETE
触发器抑制删除,那么该数目
可能小于匹配condition
的行数。如果count
为 0,
表示查询没有删除行(这并非一种错误)。
如果DELETE
命令包含RETURNING
子句,
则结果会与包含有RETURNING
列表中定义的列和值的
SELECT
语句结果相似,这些结果是在被该命令删除的
行上计算得来。
通过在USING
子句中指定其他的表,
LightDB允许在
WHERE
条件中引用其他表的列。例如,要
删除有一个给定制片人制作的所有电影,可以这样做:
DELETE FROM films USING producers WHERE producer_id = producers.id AND producers.name = 'foo';
这里实际发生的事情是在films
和
producers
之间进行连接,然后删除
所有成功连接的films
行。这种语法不
属于标准。更标准的方式是:
DELETE FROM films WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');
在一些情况下,连接形式比子查询形式更容易书写或者执行更快。
删除所有电影,但音乐剧除外:
DELETE FROM films WHERE kind <> 'Musical';
清空表films
:
DELETE FROM films;
删除已完成的任务,返回被删除行的明细:
DELETE FROM tasks WHERE status = 'DONE' RETURNING *;
删除tasks
中游标c_tasks
当前位于其上的行:
DELETE FROM tasks WHERE CURRENT OF c_tasks;
删除 citys
表中按 id
排序的前 5 行。
DELETE FROM citys order by id LIMIT 5;
这个命令符合SQL标准,不过
USING
和RETURNING
子句是
LightDB扩展,在
DELETE
中使用WITH
也是扩展。
FROM
自 LightDB 23.2开始可选,详细使用示例如下:
清除表films
:
DELETE films;
删除表中除kind不等musicals之外的所有行:
DELETE films WHERE kind <> 'Musical';