SQL

Soft Delete with Partial Index

admin by @admin ADMIN
5d ago
May 31, 2026
Public
0 0 up · 0 down Sign in to vote
Set a `deleted_at` timestamp instead of physically removing rows — preserves history and lets you "undelete". Pair with a partial index for fast queries that skip the soft-deleted rows.
SQL
Raw
-- Schema
ALTER TABLE users ADD COLUMN deleted_at TIMESTAMPTZ;

-- Partial index — indexes ONLY non-deleted rows (saves space + faster lookups)
CREATE INDEX idx_users_active_email ON users (LOWER(email))
WHERE deleted_at IS NULL;

-- Soft delete = update, not delete
UPDATE users SET deleted_at = NOW() WHERE id = $1;

-- Restore
UPDATE users SET deleted_at = NULL WHERE id = $1;

-- All non-deleted users (most queries do this — easy to forget the filter)
SELECT * FROM users WHERE deleted_at IS NULL;

-- Hide the filter in a view to make it the default
CREATE VIEW active_users AS SELECT * FROM users WHERE deleted_at IS NULL;
SELECT * FROM active_users WHERE email = 'alice@x.com';

-- Periodic hard-delete sweep — wipe rows soft-deleted > 90 days ago
DELETE FROM users WHERE deleted_at < NOW() - INTERVAL '90 days';
Tags

Save your own code snippets

Create a free account and build your private vault. Share publicly whenever you want.