DELETE — 刪除表中的行
[ WITH [ RECURSIVE ]with_query
[, ...] ] DELETE FROM [ ONLY ]table_name
[ * ] [ [ AS ]alias
] [ USINGfrom_item
[, ...] ] [ WHEREcondition
| WHERE CURRENT OFcursor_name
] [ RETURNING [ WITH ( { OLD | NEW } ASoutput_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 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
子句,則結果將類似於包含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
一起使用也是如此。
如果您在文件中看到任何不正確、不符合您對特定功能的使用經驗或需要進一步澄清的內容,請使用此表格報告文件問題。