↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

百科 / SQL 命令 / 查询与数据操作

SQL COMMAND · 查询与数据操作

DELETE

删除表中的行

DELETE查询与数据操作引入 10(基线)现存至 20 devel2 次语法变更

动词
DELETE
对象
—
引入版本
10(基线)
状态
现存
语法变更次数
2
手册小节数
7

本站手册 · 18官方文档 ↗

版本轨迹

相对 PostgreSQL 17:语法概要新增 1 行,移除 0 行。

语法铁道图 PostgreSQL 18

沿轨道从左向右阅读,分岔表示选择,绕行表示可选,回环表示重复。方框为参数,点击带下划线的参数可展开子规则。

WITH RECURSIVE with_query , DELETE FROM ONLY table_name * AS alias USING from_item , WHERE condition WHERE CURRENT OF cursor_name RETURNING WITH ( OLD NEW AS output_alias , ) * output_expression AS output_name ,

锁模式 PostgreSQL 18

具体锁模式取决于操作变体、目标对象和执行阶段;同一命令可同时取得表锁与行锁。查看完整冲突矩阵

ROW EXCLUSIVE · 表级锁

DELETE:目标表取得此模式;删除的已有行另有 FOR UPDATE 行锁。

FOR UPDATE · 行级锁

DELETE:在被删除的已有行上取得此模式;目标表同时取得 ROW EXCLUSIVE。

语法概要

相对 PostgreSQL 17 新增 1 行,移除 0 行;新增行以绿色标记。

[ WITH [ RECURSIVE ] with_query [, ...] ]
DELETE FROM [ ONLY ] table_name [ * ] [ [ AS ] alias ]
    [ USING from_item [, ...] ]
    [ WHERE condition | WHERE CURRENT OF cursor_name ]
    [ RETURNING [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ]
                { * | output_expression [ [ AS ] output_name ] } [, ...] ]

PostgreSQL 18 手册 · 查看完整参考页

描述

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。

condition

一个返回boolean类型值的表达式。只有使这个表达式返回true的行才会被删除。

cursor_name

要在WHERE CURRENT OF条件中使用的游标名。要被删除的行是最近一次从该游标中取出的那一行。该游标必须是针对DELETE目标表的非分组查询。注意,WHERE CURRENT OF不能与布尔条件同时指定。有关将游标用于WHERE CURRENT OF的更多信息,请见DECLARE。

output_alias

在RETURNING列表中为OLD或 NEW行指定的可选替代名称。

默认情况下,可通过 OLD.column_name 或OLD.*返回目标表旧值,通过 NEW.column_name 或NEW.*返回新值。提供别名后,这些名称会被隐藏,必须使用别名来引用旧行或新行。例如 RETURNING WITH (OLD AS o, NEW AS n) o.*, n.*。

output_expression

在每一行被删除后,由DELETE命令计算并返回的表达式。该表达式可以使用由table_name 命名的表或USING中列出的表的任何列名。写成 *可返回所有列。

列名或*可以用OLD或 NEW进行限定,也可以用OLD或NEW对应的 output_alias进行限定,以返回旧值或新值。未限定的列名或*,以及用目标表名称或别名限定的列名或*,都会返回旧值。

对于简单的DELETE,所有新值都将为 NULL。但是,如果某个ON DELETE 规则导致转而执行INSERT或UPDATE,那么新值可能为非NULL。

output_name

用于返回列的名称。

输出

在成功完成时,一个DELETE命令会返回以下形式的命令标签:

DELETE count

count是被删除的行数。注意,当删除被BEFORE DELETE触发器抑制时,这个数量可能小于匹配condition 的行数。如果count为 0,则该查询没有删除任何行(这不被视为错误)。

如果DELETE命令包含RETURNING 子句,其结果将类似于一个SELECT语句,其中包含 RETURNING列表中定义的列和值,并在该命令删除的行上进行计算。

注解

PostgreSQL允许通过在 USING子句中指定其他表,在 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 *;

删除游标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;

这里使用ctid之所以安全,仅仅是因为该查询会被重复执行,从而避免了ctid发生变化的问题。

兼容性

这个命令符合SQL标准,不过 USING和RETURNING子句是 PostgreSQL扩展,在 DELETE中使用WITH也是扩展。

另见

语法演化

相邻大版本之间的差异,新的在前。版本号链接到对应快照。

  1. PostgreSQL 20← 19正文更新

    正文更新
  2. PostgreSQL 19← 18正文更新

    正文更新
  3. PostgreSQL 18← 17语法变化

    + [ RETURNING [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ]正文更新
  4. PostgreSQL 17← 16正文更新

    正文更新
  5. PostgreSQL 13← 12正文更新

    正文更新
  6. PostgreSQL 12← 11语法变化

    + [ RETURNING { * | output_expression [ [ AS ] output_name ] } [, ...] ]
  7. PostgreSQL 11← 10正文更新

    正文更新

同组命令

命令动词对象版本变动最近变更
QUERIES & DATA查询与数据操作10 条↑
COPYCOPY— 196 次
在文件和表之间复制数据现存
DELETEDELETE— 182 次
删除表中的行现存
EXPLAINEXPLAIN— 195 次
显示一个语句的执行计划现存
INSERTINSERT— 193 次
在表中插入新行现存
LOCKLOCK— —
锁定表现存
MERGEMERGE— 182 次
有条件地插入、更新或删除表中的行现存
SELECTSELECT— 176 次
从表或视图中检索行现存
UPDATEUPDATE— 182 次
更新表中的行现存
VALUESVALUES— —
计算一组行现存
SELECT INTOSELECTINTO 192 次
根据查询结果定义一个新表现存