# SQL Server: Safe Bulk DELETE Using JOIN

> Delete rows using a JOIN with a preview step to avoid accidental data loss.

- URL: https://webdevrock.uk/snippets/sql-safe-bulk-delete-join/
- Tags: sql, sql-server, data-fix, delete
- Updated: 2026-02-16
- Requires: SQL Server 2008+

## Problem

You need to delete a specific set of rows based on a list or staging table, but want to verify exactly what will be removed before running the delete.

## Solution

Preview the affected rows using a SELECT, then run the DELETE using the same JOIN.

```sql
-- Preview first
SELECT t.*
FROM target_table t
JOIN #rows_to_delete d ON d.id = t.id;

-- Apply delete
BEGIN TRAN;

DELETE t
FROM target_table t
JOIN #rows_to_delete d ON d.id = t.id;

SELECT @@ROWCOUNT AS rows_deleted;

-- COMMIT;
-- ROLLBACK;
```

[Generate the whole delete (preview, backup, delete, restore) in the Data Fix Script Builder](https://webdevrock.uk/tools/data-fix-script/)

## Notes
- Always run the SELECT preview first.
- Wrapping in a transaction allows quick rollback if the row count is unexpected.
- Useful for removing duplicate or incorrectly imported data.
- Consider backing up affected rows first:

```sql
SELECT *
INTO backup_table_20260216
FROM target_table t
JOIN #rows_to_delete d ON d.id = t.id;
```
