Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

DELETE

DELETE — 删除表中的行

语法

[ WITH [ RECURSIVE ] with_query [, ...] ]
DELETE FROM [ ONLY ] table_name [ * ] [ [ AS ] alias ]
    [ USING from_item [, ...] ]
    [ WHERE condition | WHERE CURRENT OF cursor_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 fDELETE 语句的其余部分必须引用此表为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';

此处实质上执行的是 filmsproducers 之间的联接,其中所有成功联接的 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标准,但是,USINGRETURNING 子句是 PostgreSQL 扩展,同样,WITH 可以用于 DELETE 也是扩展。

参见

TRUNCATE