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_queryWITH 子句允许您指定一个或多个子查询,这些子查询可以在 DELETE 查询中按名称引用。有关详细信息,请参阅 第 7.8 节 和 SELECT。
table_name要从中删除行的表的名称(可选地是模式限定的)。如果在表名称之前指定了 ONLY,则仅从命名表中删除匹配的行。如果未指定 ONLY,则也会从继承自命名表的任何表中删除匹配的行。可选地,可以在表名称后指定 * 以显式指示包含后代表。
alias目标表的替代名称。当提供别名时,它会完全隐藏表的实际名称。例如,给定 DELETE FROM foo AS f,DELETE 语句的其余部分必须将此表引用为 f 而不是 foo。
from_item一个表表达式,允许其他表的列出现在 WHERE 条件中。这使用与 FROM 子句相同的语法 SELECT 语句; 例如,可以为表名称指定别名。不要重复目标表作为 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 语句的结果,这些列和值是根据命令删除的行计算的。
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;
此命令符合SQL标准,但 USING 和 RETURNING 子句是 PostgreSQL 扩展,并且将 WITH 与 DELETE 一起使用的能力也是如此。
如果您发现文档中有任何不正确、与您使用特定功能的体验不符或需要进一步澄清的内容,请使用此表单报告文档问题。