PostgreSQL Delete

The DELETE statement removes rows from a table based on a condition, permanently discarding the matching data.

The DELETE Statement

DELETE FROM table_name WHERE condition removes every row that matches the condition. Unlike UPDATE, DELETE doesn't change values - it removes entire rows, so the WHERE clause is the only thing standing between deleting a handful of rows and deleting the whole table.

Delete a single row

DELETE FROM employees
WHERE employee_id = 110;

A WHERE clause can combine multiple conditions with AND, OR, and IN to target exactly the rows you want removed, whether that's rows matching a status, a date range, or a list of specific IDs.

Delete rows matching multiple conditions

DELETE FROM orders
WHERE status = 'cancelled'
  AND order_date < '2024-01-01';
Note: DELETE FROM orders; with no WHERE clause removes every row in the table. If you need to clear an entire table quickly, TRUNCATE TABLE orders; does the same thing far faster, since it doesn't scan or log each row individually.

Deleting Rows Using Data From Another Table

When the rows you want to delete depend on data in a related table, PostgreSQL's DELETE ... USING clause lets you join that table into the condition, the same way UPDATE ... FROM does.

Delete using a joined table

DELETE FROM orders o
USING customers c
WHERE o.customer_id = c.customer_id
  AND c.status = 'blacklisted'
RETURNING o.order_id;
  • Preview the rows first with SELECT * FROM table WHERE <same condition>.
  • Wrap the DELETE in a transaction so you can ROLLBACK if the result looks wrong.
  • Add RETURNING to confirm which rows were actually removed.
  • Check for foreign key references - related rows may need to be deleted or updated first.
  • Index columns used in the WHERE clause so large deletes don't scan the entire table.
StatementRemovesReversible?Speed on large tables
DELETEMatching rows only, one at a time, can use WHEREYes, within a transactionSlower - scans and logs each row
TRUNCATEAll rows in the tableYes, within a transactionVery fast - deallocates data pages directly
DROP TABLEThe table structure and all its dataYes, within a transaction, until committedFast - removes the table itself
Note: Add RETURNING column1, column2 to any DELETE statement to see the full rows that were removed, which is useful for logging or for undoing a mistake by hand.

Exercise: PostgreSQL Delete

What happens when you run DELETE FROM table_name with no WHERE clause?