3 .\" Author: The PostgreSQL Global Development Group
4 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
6 .\" Manual: PostgreSQL 18.0 Documentation
7 .\" Source: PostgreSQL 18.0
10 .TH "DELETE" "7" "2025" "PostgreSQL 18.0" "PostgreSQL 18.0 Documentation"
11 .\" -----------------------------------------------------------------
12 .\" * Define some portability stuff
13 .\" -----------------------------------------------------------------
14 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
15 .\" http://bugs.debian.org/507673
16 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
17 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 .\" -----------------------------------------------------------------
21 .\" * set default formatting
22 .\" -----------------------------------------------------------------
23 .\" disable hyphenation
25 .\" disable justification (adjust text to left margin only)
27 .\" -----------------------------------------------------------------
28 .\" * MAIN CONTENT STARTS HERE *
29 .\" -----------------------------------------------------------------
31 DELETE \- delete rows of a table
35 [ WITH [ RECURSIVE ] \fIwith_query\fR [, \&.\&.\&.] ]
36 DELETE FROM [ ONLY ] \fItable_name\fR [ * ] [ [ AS ] \fIalias\fR ]
37 [ USING \fIfrom_item\fR [, \&.\&.\&.] ]
38 [ WHERE \fIcondition\fR | WHERE CURRENT OF \fIcursor_name\fR ]
39 [ RETURNING [ WITH ( { OLD | NEW } AS \fIoutput_alias\fR [, \&.\&.\&.] ) ]
40 { * | \fIoutput_expression\fR [ [ AS ] \fIoutput_name\fR ] } [, \&.\&.\&.] ]
45 deletes rows that satisfy the
47 clause from the specified table\&. If the
49 clause is absent, the effect is to delete all rows in the table\&. The result is a valid, but empty table\&.
55 .nr an-no-space-flag 1
64 provides a faster mechanism to remove all rows from a table\&.
68 There are two ways to delete rows in a table using information contained in other tables in the database: using sub\-selects, or specifying additional tables in the
70 clause\&. Which technique is more appropriate depends on the specific circumstances\&.
76 to compute and return value(s) based on each row actually deleted\&. Any expression using the table\*(Aqs columns, and/or columns of other tables mentioned in
77 USING, can be computed\&. The syntax of the
79 list is identical to that of the output list of
84 privilege on the table to delete from it, as well as the
86 privilege for any table in the
88 clause or whose values are read in the
96 clause allows you to specify one or more subqueries that can be referenced by name in the
107 The name (optionally schema\-qualified) of the table to delete rows from\&. If
109 is specified before the table name, matching rows are deleted from the named table only\&. If
111 is not specified, matching rows are also deleted from any tables inheriting from the named table\&. Optionally,
113 can be specified after the table name to explicitly indicate that descendant tables are included\&.
118 A substitute name for the target table\&. When an alias is provided, it completely hides the actual name of the table\&. For example, given
119 DELETE FROM foo AS f, the remainder of the
121 statement must refer to this table as
129 A table expression allowing columns from other tables to appear in the
131 condition\&. This uses the same syntax as the
135 statement; for example, an alias for the table name can be specified\&. Do not repeat the target table as a
137 unless you wish to set up a self\-join (in which case it must appear with an alias in the
143 An expression that returns a value of type
144 boolean\&. Only rows for which this expression returns
151 The name of the cursor to use in a
153 condition\&. The row to be deleted is the one most recently fetched from this cursor\&. The cursor must be a non\-grouping query on the
154 \fBDELETE\fR\*(Aqs target table\&. Note that
156 cannot be specified together with a Boolean condition\&. See
158 for more information about using cursors with
164 An optional substitute name for
172 By default, old values from the target table can be returned by writing
173 OLD\&.\fIcolumn_name\fR
175 OLD\&.*, and new values can be returned by writing
176 NEW\&.\fIcolumn_name\fR
178 NEW\&.*\&. When an alias is provided, these names are hidden and the old or new rows must be referred to using the alias\&. For example
179 RETURNING WITH (OLD AS o, NEW AS n) o\&.*, n\&.*\&.
182 \fIoutput_expression\fR
184 An expression to be computed and returned by the
186 command after each row is deleted\&. The expression can use any column names of the table named by
188 or table(s) listed in
191 to return all columns\&.
195 may be qualified using
198 NEW, or the corresponding
203 NEW, to cause old or new values to be returned\&. An unqualified column name, or
204 *, or a column name or
206 qualified using the target table name or alias will return old values\&.
209 \fBDELETE\fR, all new values will be
210 NULL\&. However, if an
216 to be executed instead, the new values may be non\-NULL\&.
221 A name to use for a returned column\&.
225 On successful completion, a
227 command returns a command tag of the form
241 is the number of rows deleted\&. Note that the number may be less than the number of rows that matched the
243 when deletes were suppressed by a
247 is 0, no rows were deleted by the query (this is not considered an error)\&.
253 clause, the result will be similar to that of a
255 statement containing the columns and values defined in the
257 list, computed over the row(s) deleted by the command\&.
261 lets you reference columns of other tables in the
263 condition by specifying the other tables in the
265 clause\&. For example, to delete all films produced by a given producer, one can do:
271 DELETE FROM films USING producers
272 WHERE producer_id = producers\&.id AND producers\&.name = \*(Aqfoo\*(Aq;
278 What is essentially happening here is a join between
281 producers, with all successfully joined
283 rows being marked for deletion\&. This syntax is not standard\&. A more standard way to do it is:
290 WHERE producer_id IN (SELECT id FROM producers WHERE name = \*(Aqfoo\*(Aq);
296 In some cases the join style is easier to write or faster to execute than the sub\-select style\&.
299 Delete all films but musicals:
305 DELETE FROM films WHERE kind <> \*(AqMusical\*(Aq;
324 Delete completed tasks, returning full details of the deleted rows:
330 DELETE FROM tasks WHERE status = \*(AqDONE\*(Aq RETURNING *;
340 is currently positioned:
346 DELETE FROM tasks WHERE CURRENT OF c_tasks;
355 \fBDELETE\fR, it is possible to get a similar effect using the same method described in
356 the documentation of \fBUPDATE\fR:
362 WITH delete_batch AS (
363 SELECT l\&.ctid FROM user_logs AS l
364 WHERE l\&.status = \*(Aqarchived\*(Aq
365 ORDER BY l\&.creation_date
369 DELETE FROM user_logs AS dl
370 USING delete_batch AS del
371 WHERE dl\&.ctid = del\&.ctid;
379 This command conforms to the
381 standard, except that the
387 extensions, as is the ability to use