UPDATE, DELETE and TRUNCATE
UPDATE changes values in rows that already exist, DELETE removes rows, and TRUNCATE
empties a whole table at once.
Syntax
Order of execution: FROM (and any other table) → WHERE → SET or delete → RETURNING
WHERE picks the rows before anything changes. Leave it out and every row in the table is
changed or deleted.
CodeUPDATE table_name SET column1 = expression, column2 = expression FROM other_table -- optional WHERE condition RETURNING column1, ...; DELETE FROM table_name WHERE condition RETURNING column1, ...; TRUNCATE table_name [RESTART IDENTITY];
| Part | Meaning |
|---|---|
SET column = expression | the new value; it can use the old one, like price * 0.9 |
FROM other_table | another table to match rows against, joined in WHERE (MySQL joins it before SET instead; Oracle before 23ai uses a subquery or MERGE) |
WHERE | which rows change; no WHERE means every row |
RETURNING | show the changed or deleted rows (PostgreSQL; SQL Server uses OUTPUT) |
TRUNCATE | remove every row at once; it takes no WHERE |
RESTART IDENTITY | also start the id counter again at 1 (PostgreSQL; MySQL and SQL Server always reset it) |
Examples
Check first
Make sure you have the right rows before you change them.
Code-- 1. See the rows the WHERE picks SELECT product_id, product_name, stock FROM products WHERE product_id = 4; -- 2. Same WHERE, now change them UPDATE products SET stock = 25 WHERE product_id = 4;
Update with expressions
Change values based on what is already there, in one or more columns.
Code-- Toys: 10% off and 20 more in stock UPDATE products SET price = price * 0.9, stock = stock + 20 WHERE category_id = 8 RETURNING product_name, price, stock;
Update from another table
Pick the rows to change using values stored in a different table.
Code-- Mark every product in the 'Smart Home' category unavailable UPDATE products SET is_available = false FROM categories WHERE categories.category_id = products.category_id AND categories.category_name = 'Smart Home' RETURNING products.product_name, products.is_available;
Delete rows
Remove only the rows you no longer need.
Code-- Remove the low-rated reviews DELETE FROM reviews WHERE rating <= 2 RETURNING review_id, rating; -- Fails: orders still point to customer 1 DELETE FROM customers WHERE customer_id = 1;
Empty a table
Remove every row of a table at once.
Code-- DELETE without WHERE removes every row, but the id counter keeps going DELETE FROM accounts; -- TRUNCATE is faster; RESTART IDENTITY also sets the next id back to 1 TRUNCATE accounts RESTART IDENTITY;
DELETE, TRUNCATE or DROP
All three get rid of data, but they remove different things.
DELETE | TRUNCATE | DROP TABLE | |
|---|---|---|---|
| Removes | the rows WHERE picks, or all | every row | the table itself: rows, columns, indexes |
| The table afterwards | still there | still there, empty | gone |
WHERE | yes | no | no |
| Speed on a big table | slow: one row at a time | fast | fast |
| Id counter | keeps going | MySQL and SQL Server reset it; PostgreSQL with RESTART IDENTITY | gone with the table |
Undo with ROLLBACK | everywhere | PostgreSQL and SQL Server; not MySQL or Oracle | PostgreSQL and SQL Server; not MySQL or Oracle |
TRUNCATE is refused while another table's foreign key points to the table; PostgreSQL accepts
TRUNCATE … CASCADE, which empties those tables too.
Remember
- No
WHEREmeans every row. Run theWHEREas aSELECTfirst. ANDis checked beforeOR: use brackets orINwhen you mix them.UPDATE ... FROMchanges each row once, even when it matches several rows of the other table.DELETEkeeps the id counter going; PostgreSQL'sTRUNCATE ... RESTART IDENTITYresets it.- A foreign key can refuse a
DELETEwhile other rows still point to the row.
Practice
- Clear Failed UPI and Card Payments (Easy)
- Reward Customers Who Reviewed (Easy)
- Start the Reviews Over (Medium)