Skip to main content

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
DELETE removes whole rows. There is no undo outside a transaction, so the habit worth building is to write the WHERE first and look at what it selects. These examples use the sakila_practice database from INSERT. Run the setup block there again before you start, then open the client with mysql -u root -p sakila_practice.

How DELETE works

Replace TABLE_NAME with the table and CONDITION with the test that picks the rows to remove. There is no column list. A DELETE takes the entire row, so emptying 1 column is an UPDATE setting it to NULL.

Examples

1) Look first, then delete

Write the WHERE as a SELECT and read the rows you are about to lose.
One row, and it is the one you meant. Now change the front of the statement and leave the WHERE untouched.
A DELETE reports rows affected and nothing else. An UPDATE prints a second line with Rows matched and Changed; a DELETE has no equivalent.

2) A WHERE that matches nothing is not an error

Nothing went wrong and nothing happened. 0 rows affected after a delete you expected to work means the WHERE is wrong, and the statement will not tell you so.

Without a WHERE it empties the table

Safe update mode refuses this shape, exactly as it refuses an UPDATE with no key in its WHERE. UPDATE shows the ERROR 1175 it raises, and mysql -u root -p --safe-updates sakila_practice turns it on for the whole session.

TRUNCATE empties it differently

The table is empty, so insert a row and look at its id.
The counter carried on from the rows the DELETE removed. TRUNCATE TABLE does not.
TRUNCATE drops the table and builds an empty one, which is why it reports 0 rows affected however many rows it removed and why the counter starts over. It takes no WHERE, it cannot be rolled back, and it fires no DELETE triggers. Use TRUNCATE to reset a table to nothing, and DELETE for everything else.

Summary

  • Write DELETE FROM table WHERE condition, and run the WHERE as a SELECT first.
  • Expect a row count and no Rows matched line.
  • Read 0 rows affected as a WHERE that found nothing, not as a failure.
  • Leave out the WHERE and the table is emptied, with no confirmation step.
  • Use TRUNCATE TABLE to empty and reset a table, knowing it cannot be undone.

See also

  • UPDATE — changing rows, and the safe update guard
  • WHERE — the clause that decides which rows go
  • Transactions — the only way to take a DELETE back
  • Soft deletes in MySQL — marking rows gone instead of removing them