HTML CSS Bootstrap JavaScript jQuery MySQL PHP Data Mining

MySQL DELETE Statement

Written by RedoHub Team · Last updated: August 1, 2026

The DELETE statement permanently removes rows from a table. It is the D in CRUD — Delete. Once a row is deleted, it is gone — unless you have a backup or are using transactions. This makes DELETE one of the most powerful and most dangerous commands in MySQL, so it must always be used with care.


Syntax

DELETE FROM table_name
WHERE condition;
Warning: The WHERE clause is technically optional, but omitting it deletes every row in the table. Always include a WHERE clause unless you truly intend to clear the entire table.

Sample Table

All examples on this page use the following students table:

idnamecityage
1Rahim UddinDhaka22
2Sara BegumChittagong20
3Karim AliSylhet23
4Nila AkterDhaka21
5Rafi HossainRajshahi24

Deleting a Single Row

The safest way to delete one specific row is to target it by its primary key:

DELETE FROM students
WHERE id = 3;

This removes only Karim Ali's row. MySQL confirms:

Query OK, 1 row affected (0.01 sec)

Deleting Multiple Rows

If the WHERE condition matches more than one row, all matching rows are deleted at once:

-- Delete all students from Dhaka
DELETE FROM students
WHERE city = 'Dhaka';

This removes both Rahim Uddin (id=1) and Nila Akter (id=4) in a single operation.


Verify Before You Delete

Just like with UPDATE, always run a SELECT with the same WHERE condition before deleting, to confirm exactly which rows will be removed:

-- Step 1: Preview what will be deleted
SELECT * FROM students WHERE city = 'Dhaka';

-- Step 2: If the result looks correct, proceed
DELETE FROM students WHERE city = 'Dhaka';
Tip: Making "select before delete" a habit takes only a few seconds and can prevent the kind of accidental data loss that takes hours — or days — to recover from.

Deleting All Rows

To remove every row from a table without dropping the table itself, omit the WHERE clause:

DELETE FROM students;

The table structure (columns, constraints, indexes) remains intact — only the data is removed. The AUTO_INCREMENT counter is not reset by DELETE.


DELETE vs TRUNCATE

Both DELETE and TRUNCATE remove rows, but they behave differently:

Feature DELETE TRUNCATE
Can use WHERE ✔ Yes ✘ No
Resets AUTO_INCREMENT ✘ No ✔ Yes
Can be rolled back ✔ Yes (in a transaction) ✘ No
Fires DELETE triggers ✔ Yes ✘ No
Speed on large tables Slower Much faster

Use DELETE when you need to remove specific rows or want the ability to roll back the operation. Use TRUNCATE when you need to wipe all data quickly and reset the ID counter.


DELETE and Foreign Keys

If a row in a parent table is referenced by rows in a child table through a foreign key, MySQL will block the delete by default (the RESTRICT behavior):

-- Will fail if orders exist for customer id=1
DELETE FROM customers WHERE id = 1;
-- ERROR 1451: Cannot delete or update a parent row: a foreign key constraint fails

To allow it, either delete the child rows first, or define the foreign key with ON DELETE CASCADE so child rows are removed automatically.


Key Points to Remember

  • DELETE FROM table WHERE condition — always include WHERE to avoid wiping the whole table.
  • Target rows by primary key for precise, single-row deletes.
  • Run a SELECT with the same condition first to preview what will be deleted.
  • DELETE without WHERE removes all rows but keeps the table structure and does not reset AUTO_INCREMENT.
  • Use TRUNCATE when you want to clear all rows quickly and reset the ID counter.
  • Foreign key constraints can block deletes — remove child rows first, or use ON DELETE CASCADE.
What's next? You have now completed all four CRUD operations. The next section covers Filtering & Sorting — starting with the WHERE Clause, where you will learn how to write precise conditions to target exactly the data you need.

Common Mistakes to Avoid

Running DELETE without a WHERE clause by accident. Forgetting to highlight the whole statement in a SQL client, or a typo that drops the condition, can wipe an entire table in production with no warning.
Expecting DELETE to reset AUTO_INCREMENT. Even after deleting every row, the next inserted row continues from where the counter left off — use TRUNCATE if you specifically need the counter reset to 1.
Deleting a parent row without checking for related child rows first. If a foreign key uses the default RESTRICT behavior, MySQL blocks the delete — plan the deletion order (children first) or use ON DELETE CASCADE deliberately.

Try It: Delete Inside a Transaction

A second example — wrapping a delete in a transaction so it can be rolled back if something looks wrong before committing:

START TRANSACTION;

DELETE FROM students WHERE age > 30;

-- Check the result looks right, then either:
COMMIT;
-- or, if something's wrong:
-- ROLLBACK;

Frequently Asked Questions

Q: Is there a way to recover deleted rows?

A: Not through MySQL itself unless the delete happened inside an uncommitted transaction — recovery otherwise depends on a database backup taken before the delete.

Q: What's the fastest way to delete every row in a huge table?

A: TRUNCATE TABLE table_name; — it's much faster than DELETE without WHERE because it doesn't log individual row deletions.

Q: Can I delete rows from multiple tables in one statement?

A: Yes, with a multi-table DELETE using a join. See the official DELETE documentation for the exact syntax.