Skip to main content

PostgreSQL DELETE

Introduction

The DELETE command is one of the fundamental Data Manipulation Language (DML) operations in PostgreSQL. It allows you to remove records from a database table based on specified conditions. Understanding how to properly use DELETE statements is crucial for maintaining your database's data integrity and performing necessary data cleanup operations.

In this tutorial, you'll learn:

  • The basic syntax of DELETE statements
  • How to delete specific rows using WHERE clauses
  • How to delete all rows from a table
  • Safe deletion practices and common pitfalls to avoid
  • Using DELETE with subqueries and joins
  • Returning deleted data

Basic DELETE Syntax

The basic syntax for a DELETE statement in PostgreSQL is:

sql
DELETE FROM table_name
WHERE condition;

Let's break down the components:

  • DELETE FROM specifies the table from which you want to remove records
  • WHERE (optional) defines the condition that identifies which rows to delete
  • If you omit the WHERE clause, all rows in the table will be deleted

Setting Up Example Data

Before we dive into examples, let's create a sample table to work with:

sql
CREATE TABLE employees (
employee_id SERIAL PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
department VARCHAR(50),
salary NUMERIC(10, 2),
hire_date DATE
);

INSERT INTO employees (first_name, last_name, department, salary, hire_date)
VALUES
('John', 'Smith', 'IT', 75000.00, '2018-06-20'),
('Mary', 'Johnson', 'HR', 65000.00, '2019-03-15'),
('Robert', 'Brown', 'Finance', 82000.00, '2017-11-10'),
('Patricia', 'Williams', 'IT', 78000.00, '2020-01-05'),
('Michael', 'Jones', 'Marketing', 68000.00, '2021-02-18'),
('Linda', 'Davis', 'HR', 62000.00, '2022-07-12');

Deleting Specific Rows

Example 1: Delete a Single Row by Primary Key

Let's delete the employee with ID 3:

sql
DELETE FROM employees 
WHERE employee_id = 3;

Output:

DELETE 1

The output shows that 1 row was deleted. Now if we check our table:

sql
SELECT * FROM employees ORDER BY employee_id;

Result:

 employee_id | first_name | last_name | department | salary  |  hire_date  
-------------+------------+-----------+------------+---------+-------------
1 | John | Smith | IT | 75000.00 | 2018-06-20
2 | Mary | Johnson | HR | 65000.00 | 2019-03-15
4 | Patricia | Williams | IT | 78000.00 | 2020-01-05
5 | Michael | Jones | Marketing | 68000.00 | 2021-02-18
6 | Linda | Davis | HR | 62000.00 | 2022-07-12
(5 rows)

Notice that the row with employee_id 3 (Robert Brown) has been removed.

Example 2: Delete Rows Based on a Condition

Let's delete all employees from the HR department:

sql
DELETE FROM employees 
WHERE department = 'HR';

Output:

DELETE 2

This shows that 2 rows were deleted. Let's check our table again:

sql
SELECT * FROM employees ORDER BY employee_id;

Result:

 employee_id | first_name | last_name | department | salary  |  hire_date  
-------------+------------+-----------+------------+---------+-------------
1 | John | Smith | IT | 75000.00 | 2018-06-20
4 | Patricia | Williams | IT | 78000.00 | 2020-01-05
5 | Michael | Jones | Marketing | 68000.00 | 2021-02-18
(3 rows)

All HR department employees (Mary Johnson and Linda Davis) have been removed.

Deleting All Rows

To delete all rows from a table, simply omit the WHERE clause:

sql
DELETE FROM employees;

⚠️ Warning: This will remove ALL rows from the table. Use with extreme caution!

If you really need to delete all rows, consider using the TRUNCATE command instead, which is faster for large tables:

sql
TRUNCATE TABLE employees;

The TRUNCATE command is faster because it doesn't scan each row before deleting it.

Using DELETE with Multiple Conditions

You can combine multiple conditions in your WHERE clause using logical operators:

sql
-- Restore our data for the next examples
INSERT INTO employees (first_name, last_name, department, salary, hire_date)
VALUES
('John', 'Smith', 'IT', 75000.00, '2018-06-20'),
('Mary', 'Johnson', 'HR', 65000.00, '2019-03-15'),
('Robert', 'Brown', 'Finance', 82000.00, '2017-11-10'),
('Patricia', 'Williams', 'IT', 78000.00, '2020-01-05'),
('Michael', 'Jones', 'Marketing', 68000.00, '2021-02-18'),
('Linda', 'Davis', 'HR', 62000.00, '2022-07-12');

-- Delete employees in IT department with salaries over 75000
DELETE FROM employees
WHERE department = 'IT' AND salary > 75000;

After running this command, Patricia Williams would be deleted because she works in IT and has a salary over 75000.

Using DELETE with Subqueries

You can use subqueries with DELETE to perform more complex deletions:

sql
-- Delete the highest paid employee
DELETE FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);

This will delete Robert Brown since he has the highest salary (82000).

RETURNING Clause: Getting Information About Deleted Rows

PostgreSQL's RETURNING clause lets you retrieve the data that's being deleted:

sql
-- Delete employees hired before 2019 and return their information
DELETE FROM employees
WHERE hire_date < '2019-01-01'
RETURNING employee_id, first_name, last_name, hire_date;

Result:

 employee_id | first_name | last_name |  hire_date
-------------+------------+-----------+-------------
1 | John | Smith | 2018-06-20
3 | Robert | Brown | 2017-11-10
(2 rows)

This is especially useful when you need to keep track of what was deleted or perform additional operations with the deleted data.

Using DELETE with JOINs

PostgreSQL allows using CTEs (Common Table Expressions) to perform complex deletions involving joined tables:

sql
-- First, let's create a departments table
CREATE TABLE departments (
department_id SERIAL PRIMARY KEY,
department_name VARCHAR(50),
status VARCHAR(20)
);

INSERT INTO departments (department_name, status)
VALUES
('IT', 'Active'),
('HR', 'Active'),
('Finance', 'Active'),
('Marketing', 'Inactive');

-- Delete employees from inactive departments
WITH inactive_departments AS (
SELECT department_name
FROM departments
WHERE status = 'Inactive'
)
DELETE FROM employees
WHERE department IN (SELECT department_name FROM inactive_departments);

This will delete Michael Jones since he's in the Marketing department, which is inactive.

Best Practices for DELETE Operations

  1. Always use a WHERE clause unless you truly intend to delete all rows.
  2. Test with SELECT first - before executing a DELETE, test your WHERE condition with a SELECT statement to verify you're targeting the correct rows:
sql
-- Test first with SELECT
SELECT * FROM employees WHERE department = 'HR';

-- Then if results look correct, run the DELETE
DELETE FROM employees WHERE department = 'HR';
  1. Use transactions to safely run DELETE operations with rollback capability:
sql
BEGIN;
DELETE FROM employees WHERE department = 'IT';
-- Check if correct rows were deleted
-- If something went wrong, you can ROLLBACK
-- ROLLBACK;
-- If everything looks good
COMMIT;
  1. Consider foreign key constraints - PostgreSQL will prevent you from deleting rows that are referenced by foreign keys in other tables unless you've set up cascading deletes.

  2. Use EXPLAIN to understand the execution plan for complex DELETE operations:

sql
EXPLAIN DELETE FROM employees WHERE salary > 70000;

Performance Considerations

For very large tables, consider:

  1. Batched deletes for better performance:
sql
-- Delete in smaller batches of 1000 rows
DELETE FROM large_table
WHERE some_condition
LIMIT 1000;
-- Repeat as needed
  1. Partitioned tables make deletions more efficient when removing entire partitions.

  2. Consider TRUNCATE for removing all data from large tables, as it's much faster than DELETE.

Common Errors and Troubleshooting

  1. Foreign key violations:

    ERROR: update or delete on table "employees" violates foreign key constraint "fk_department" on table "assignments"

    Solution: Either delete dependent records first or set up CASCADE on your foreign keys.

  2. Permission issues:

    ERROR: permission denied for table employees

    Solution: Ensure your database user has DELETE privileges on the table.

Summary

In this tutorial, you've learned:

  • How to delete specific rows using the DELETE statement with WHERE clauses
  • Techniques for deleting based on complex conditions
  • Using subqueries and the RETURNING clause with DELETE
  • Best practices for safe and efficient DELETE operations

The DELETE statement is a powerful tool in PostgreSQL data management. When used carefully with proper WHERE conditions, it allows you to maintain clean, accurate data in your database.

Practice Exercises

  1. Create a customers table with fields for customer_id, name, email, and status. Insert several records and then write a DELETE statement to remove inactive customers.

  2. Write a DELETE statement that removes duplicate records from a table, keeping only the record with the lowest ID.

  3. Create two related tables with a foreign key constraint, then practice deleting records while handling the constraint.

Additional Resources



If you spot any mistakes on this website, please let me know at feedback@compilenrun.com. I’d greatly appreciate your feedback! :)