Warming up the neural circuits...
DELETE removes rows permanently. Like UPDATE, it's dangerous without WHERE. By the end of this module you will:
What it is: DELETE FROM is a DML command that permanently removes rows from a table. You specify which rows to delete using a WHERE clause — without it, all rows are deleted.
Why we use it: Data sometimes needs to be removed — test data cleanup, GDPR compliance, removing spam, or clearing temporary records. DELETE is the tool for permanent removal.
When we use it: When removing specific records, cleaning up test data, complying with data retention policies, or clearing temporary/staging data.
-- Delete a specific user
DELETE FROM users
WHERE id = 4;What it is: Without WHERE, DELETE removes every row in the table. This is almost always a catastrophic mistake — in production, it can destroy millions of records instantly.
Why we use it: This section exists to warn you. Like UPDATE, forgetting WHERE on DELETE is one of the most common causes of data loss. Always write WHERE first, then the of the DELETE.
When we use it: Never intentionally. This is a mistake to avoid.
-- DANGER: The table is now empty!
DELETE FROM users;Pro Rule: Never write a DELETE statement without writing the WHERE clause first. Always test with SELECT.
What it is: RETURNING (PostgreSQL extension) returns the deleted rows immediately after the DELETE executes. It's like combining DELETE and SELECT in one atomic operation.
Why we use it: After deleting a record, you might need to log what was removed, return the deleted data to the client, or verify what was affected.
When we use it: In audit logging, REST APIs that return deleted resources, or when you need to verify what was removed.
DELETE FROM users
WHERE id = 4
RETURNING *;What it is: Soft delete is a pattern where instead of actually removing a row, you mark it as deleted (usually with a deleted_at timestamp). The row still exists in the database but is hidden from queries. Hard delete permanently removes the row.
Why we use it: Soft delete allows data recovery, preserves referential integrity (no orphaned records), maintains audit trails, and supports analytics on deleted data. It's the standard approach for user-facing applications.
When we use it: Use soft delete for important data (users, posts, orders) and hard delete for temporary data (sessions, logs, test data).
| Strategy | Command | Use Case |
|---|---|---|
| Hard Delete | DELETE FROM... | Temporary data, logs, GDPR compliance |
| Soft Delete | UPDATE table SET deleted_at = NOW()... | Users, posts, orders (allows recovery) |
-- Add a soft delete column
ALTER TABLE users ADD COLUMN deleted_at TIMESTAMPTZ;
-- "Delete" a user (soft delete)
UPDATE users
SET deleted_at = NOW()
WHERE id = 5;
-- Query active users (exclude soft-deleted)
SELECT * FROM users WHERE deleted_at IS NULL;
Why soft delete? Instagram doesn't actually delete your photos when you "delete" them. They mark them as deleted and hide them from the UI. This allows recovery and preserves data for analytics.
What it is: The safe DELETE pattern is a workflow: always test your WHERE clause with SELECT first, verify the rows that will be deleted, then run the DELETE with the same WHERE clause.
Why we use it: This pattern prevents accidental mass deletes. By previewing which rows will be affected, you can catch mistakes before they cause permanent data loss.
When we use it: Every time you run a DELETE in production. It takes 5 seconds and can save hours of recovery work (or worse, unrecoverable data loss).
-- Step 1: Test with SELECT
SELECT * FROM users WHERE is_active = false;
-- Step 2: Verify the rows you want to delete
-- Step 3: Run DELETE with the same WHERE clause
DELETE FROM users WHERE is_active = false;Using your courses table:
deleted_at column to your courses tabledeleted_atNext up: You know the core operations. In the next module, you'll learn pattern matching with LIKE and ILIKE for text searching.