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_nameWHERE CURRENT OF條件中使用的遊標的名稱。要刪除的行是最近從該遊標中獲取的行。該遊標必須是DELETE目標表上的非分組查詢。請注意,WHERE CURRENT OF不能與布林條件一起指定。有關使用WHERE CURRENT OF的遊標的更多資訊,請參閱DECLARE。
output_aliasRETURNING 列表中的 OLD 或 NEW 行的可選替代名稱。
預設情況下,可以透過編寫 OLD. 或 column_nameOLD.* 返回目標表中的舊值,透過編寫 NEW. 或 column_nameNEW.* 返回新值。提供別名時,將隱藏這些名稱,並且必須使用別名引用舊行或新行。例如 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一起使用也是如此。
如果您在文件中看到任何不正確、不符合您對特定功能的使用經驗或需要進一步澄清的內容,請使用此表格報告文件問題。