支援的版本:目前 (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 { * | 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_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';

這裡發生的本質上是 filmsproducers 之間的聯結,所有成功聯結的 films 資料列都會被標記為刪除。這種語法不是標準的。一種更標準的做法是

DELETE FROM films
  WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');

在某些情況下,使用連接 (join) 樣式比子查詢 (sub-select) 樣式更容易編寫或執行速度更快。

範例

刪除所有電影,除了音樂劇

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 的擴充功能,如同使用 WITHDELETE 的能力。

參閱

TRUNCATE

提交更正

如果您在文件中發現任何不正確、與特定功能的體驗不符或需要進一步澄清的地方,請使用此表單報告文件問題。