DELETE permanently removes selected rows from a PostgreSQL table.
DELETE removes rows that meet a given WHERE condition. Without WHERE, it wipes the entire table. RETURNING can output affected rows for verification.
Use a primary-key filter. Example: DELETE FROM Customers WHERE id = 42 RETURNING *;
confirms the exact customer removed.
Combine USING to reference other tables.Example: remove customers with no orders: DELETE FROM Customers c USING Orders o WHERE c.id = o.customer_id AND o.id IS NULL;
ONLY restricts deletion to the specified table, skipping inheriting tables.Syntax: DELETE FROM ONLY Products WHERE stock = 0;
Use a SELECT with the same WHERE clause or append RETURNING to capture deleted data for audit logs.
Wrap DELETE in a loop with LIMIT and COMMIT per batch to avoid long locks: DELETE FROM Orders WHERE order_date < NOW() - INTERVAL '2 years' LIMIT 10000;
TRUNCATE is faster but bypasses triggers.Prefer DELETE
when triggers or RETURNING data are needed.
DELETE logs each row and fires triggers. TRUNCATE logs at the table level. For mass purges, TRUNCATE followed by VACUUM is quicker.
.
No. Space is marked for reuse. Run VACUUM or autovacuum will reclaim it later.
Yes. Until COMMIT, you can ROLLBACK to restore all deleted rows.
Use TRUNCATE for full-table purges when you don’t need row-level triggers or RETURNING data.