DELETE — 删除表中的行
[ WITH [ RECURSIVE ]with_query
[, ...] ] DELETE FROM [ ONLY ]table_name
[ * ] [ [ AS ]alias
] [ USINGfrom_item
[, ...] ] [ WHEREcondition
| WHERE CURRENT OFcursor_name
] [ RETURNING { * |output_expression
[ [ AS ]output_name
] } [, ...] ]
DELETE
从指定表中删除符合WHERE
子句的行。如果WHERE
子句不存在,则会删除表中的所有行。结果是一个有效但为空的表。
TRUNCATE
提供了一种更快捷的机制,可用于从表中删除所有行。
有两种方法可以使用数据库中其他表中的信息在表中删除行:使用子查询或在USING
子句中指定其他表。哪种技术更合适取决于具体情况。
可选的RETURNING
子句导致DELETE
计算并返回实际删除的每一行的值。可以使用表的列以及USING
中提到的其他表的列来计算任何表达式。RETURNING
列表的语法与SELECT
的输出列表的语法相同。
您必须对要从中删除行的表具有DELETE
权限,以及对USING
子句中或在condition
中读取其值的任何表的SELECT
权限。
with_query
WITH
子句允许您指定一个或多个子查询,可通过名称在DELETE
查询中引用它们。有关详细信息,请参见第 7.8 节 和SELECT。
table_name
要从中删除行的表(可选进行模式限定)的名称。如果在表名称前指定了ONLY
,则只删除匹配行从命名的表中。如果未指定ONLY
,则还会从继承自命名表的任何表中删除匹配行。此外,可以在表名称后指定*
以明确指示包括后代表。
alias
目标表的替代名称。提供别名时,它会完全隐藏表的实际名称。例如,给定DELETE FROM foo AS f
,DELETE
语句的其余部分必须引用此表为f
,而不是foo
。
from_item
一个允许出现在 WHERE
条件中的其他表的列的表表达式。这使用了与一个 SELECT
语句中的 FROM
子句相同的语法;举例来说,可以为表名指定一个别名。不要将目标表作为 from_item
重复,除非你想设置一个自连接(在这种情况下,它必须出现在 from_item
中并具有别名)。
条件
返回类型为 boolean
的表达。只有此表达返回 true
的行才会被删除。
游标名称
在 WHERE CURRENT OF
条件中使用的游标的名称。要删除的行是最近从该游标中获取的一行。该游标必须是针对 DELETE
的目标表的非分组查询。注意 WHERE CURRENT OF
不能与布尔条件一同指定。有关在 WHERE CURRENT OF
中使用游标的更多信息,请参见 DECLARE。
输出表达式
在每次删除一行后,由 DELETE
命令计算并返回的表达式。该表达式可以使用 table_name
所命名的表或表列表中 USING
中列出的任何列名。写 *
返回所有列。
输出名称
用于返回的列的名称。
成功完成后,一个 DELETE
命令返回格式如下:的命令标记
DELETE count
count
是所删除的行数。注意在 BEFORE DELETE
触发器抑制了删除时,此数目可能小于与 condition
匹配的行数。如果 count
是 0,则没有行被该查询删除(这不会被视为一个错误)。
如果 DELETE
命令包含一个 RETURNING
子句,则结果将类似于一个 SELECT
语句,其中包含 RETURNING
列表中定义的该命令删除的行上的列和值。
PostgreSQL 允许你在 WHERE
条件中指定其他表中的 USING
子句中的列。例如,要删除由给定的制作人制作的所有电影,可以执行
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 *;
删除游标 c_tasks
当前所定位 tasks
行
DELETE FROM tasks WHERE CURRENT OF c_tasks;
虽然 DELETE
没有 LIMIT
子句,但可以使用 UPDATE
文档 中所述的相同方法获得类似的效果。
WITH delete_batch AS ( SELECT l.ctid FROM user_logs AS l WHERE l.status = 'archived' ORDER BY l.creation_date FOR UPDATE LIMIT 10000 ) DELETE FROM user_logs AS dl USING delete_batch AS del WHERE dl.ctid = del.ctid;
此命令符合SQL标准,但是,USING
和 RETURNING
子句是 PostgreSQL 扩展,同样,WITH
可以用于 DELETE
也是扩展。