2025年9月25日: PostgreSQL 18 釋出!
支援的版本:當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

DELETE

DELETE — 刪除表中的行

概要

[ 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 ] } [, ...] ]

描述

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重複。

condition

返回boolean型別值的表示式。只有當此表示式返回true的行才會被刪除。

cursor_name

WHERE CURRENT OF條件中使用的遊標的名稱。要刪除的行是最近從該遊標中獲取的行。該遊標必須是DELETE目標表上的非分組查詢。請注意,WHERE CURRENT OF不能與布林條件一起指定。有關使用WHERE CURRENT OF的遊標的更多資訊,請參閱DECLARE

output_alias

RETURNING 列表中的 OLDNEW 行的可選替代名稱。

預設情況下,可以透過編寫 OLD.column_nameOLD.* 返回目標表中的舊值,透過編寫 NEW.column_nameNEW.* 返回新值。提供別名時,將隱藏這些名稱,並且必須使用別名引用舊行或新行。例如 RETURNING WITH (OLD AS o, NEW AS n) o.*, n.*

output_expression

在刪除每一行後,由DELETE命令計算並返回的表示式。該表示式可以使用table_name指定的表或USING中列出的表中的任何列名。編寫*以返回所有列。

列名或*可以使用OLDNEW,或者OLDNEW對應的output_alias來限定,以返回舊值或新值。未限定的列名,或*,或使用目標表名或別名限定的列名或*將返回舊值。

對於簡單的DELETE,所有新值都將是NULL。但是,如果ON DELETE規則導致執行INSERTUPDATE,則新值可能不是NULL

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';

這裡本質上發生的是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

提交更正

如果您在文件中看到任何不正確、不符合您對特定功能的使用經驗或需要進一步澄清的內容,請使用此表格報告文件問題。