Phase 6 · Building tables and changing data · Topic 6.3

INSERT, UPDATE and DELETE

Must know

INSERT adds new rows, UPDATE changes values in existing rows, and DELETE removes rows — and both UPDATE and DELETE act on every row their WHERE matches, or on every row of the table if there is no WHERE.

Not started

Step 1 Understand it

Why you need it. A is only useful if it can be kept up to date: new customers, price changes, cancelled orders. These three statements do all of that — and one missing can change or wipe every , so they deserve care.

New words in this topic (tap one to see what it means)

Watch it happen

AnimationINSERT adds rows, UPDATE changes them, DELETE removes them
Read the animation as text
  1. Safe habit: run the WHERE as a SELECT first and look at the rows it picks. Here: Dara and Eli.
  2. Then turn it into the UPDATE. SET salary = salary + 5000 uses each row's OLD value to work out the new one.
  3. Only the matching rows change: Dara 65000, Eli 50000. Without the WHERE, every row in the table would get the raise.

Picture it

flowchart LR
  T["a table"] --> I["INSERT<br/>adds rows"]
  T --> U["UPDATE … WHERE<br/>changes matching rows"]
  T --> D["DELETE … WHERE<br/>removes matching rows"]
  U -.->|"no WHERE"| ALL["every row changed"]
  D -.->|"no WHERE"| ALL2["every row removed"]
and act on whatever their WHERE matches. Leave the WHERE out and they act on every row in the .

The idea

INSERT INTO table (columns) VALUES (…) adds a row; list the so the order is clear. INSERT … SELECT copies rows from a . UPDATE table SET column = value WHERE condition changes matching rows, and the new value can use the old one (salary = salary + 5000). DELETE FROM table WHERE condition removes matching rows. An — INSERT … ON CONFLICT DO UPDATE — inserts a row, or updates it if the key already exists.

The shape of it

sql
INSERT INTO t (col1, col2) VALUES (v1, v2);
UPDATE t SET col1 = new_value WHERE condition;
DELETE FROM t WHERE condition;

Words in lower case are the parts you fill in.

How it works, step by step

  1. adds Ravi as customer 7. The are checked first.
  2. UPDATE employees SET salary = salary + 5000 WHERE dept_id = 2: Dara and Eli get the raise, nobody else.
  3. DELETE FROM customers WHERE customer_id = 6 removes Tom's duplicate sign-up (he has no orders, so the allows it).
  4. Upsert: inserting product 7 again hits the , so DO UPDATE changes its price instead.
  5. Safe habit: write SELECT * FROM t WHERE … first, check the rows, then turn it into the UPDATE or DELETE.

Analogy

Editing a spreadsheet. INSERT adds a new line at the bottom. UPDATE is find-and-replace — and WHERE is the "only in this selection" box. DELETE removes lines. Forgetting WHERE is "replace all" across the whole sheet.

Where the analogy breaks

A spreadsheet has Undo. The database doesn't: once a change is committed, it is permanent. That is why you run the WHERE as a first, and use (next lesson) so you can roll back.

Worked examples

INSERT a new customer

sql
INSERT INTO customers (customer_id, name, email, city, signup_date)
VALUES (7, 'Ravi', 'ravi@mail.com', 'Leeds', '2024-03-25');
SELECT customer_id, name, city
FROM customers
WHERE city = 'Leeds'
ORDER BY customer_id;

3 rows

customer_idnamecity
2TomLeeds
6TomLeeds
7RaviLeeds

UPDATE using the old value

sql
UPDATE employees
SET salary = salary + 5000
WHERE dept_id = 2;
SELECT name, salary
FROM employees
WHERE dept_id = 2
ORDER BY name;

2 rows

namesalary
Dara65000
Eli50000

DELETE one row

sql
DELETE FROM customers
WHERE customer_id = 6;
SELECT customer_id, name
FROM customers
ORDER BY customer_id;

5 rows

customer_idname
1Priya
2Tom
3Lena
4Omar
5Zoe

Every run on this page starts from the original data, so this delete doesn't affect other examples.

Upsert: insert, or update if it already exists

sql
INSERT INTO products (product_id, product_name, category, price)
VALUES (7, 'Phone case', 'Electronics', 12)
ON CONFLICT (product_id) DO UPDATE SET price = excluded.price;
SELECT product_id, product_name, price
FROM products
WHERE category = 'Electronics'
ORDER BY product_id;

2 rows

product_idproduct_nameprice
6Headphones40
7Phone case12

excluded means "the row you tried to insert". The phone case already existed, so its price was updated from 15 to 12.

Must-know points

  • Always list the columns in INSERT; don't rely on the table's column order.
  • UPDATE and DELETE without WHERE change every row.
  • Run the WHERE as a SELECT first, and check how many rows it hits.
  • INSERT INTO t (…) SELECT … copies rows from a query.
  • An upsert inserts or updates in one atomic statement.

Common mistakes

  • Forgetting WHERE on an UPDATE or DELETE.
  • Deleting parent rows that child rows still reference — the foreign key refuses, or cascades if set to.
  • Updating with a value computed from another table without checking the returns one row per target row.

In other databases

  • and support RETURNING to see the rows you changed: DELETE FROM t WHERE … RETURNING *. uses OUTPUT.
  • UPDATE with a join: PostgreSQL UPDATE t SET … FROM other WHERE …; UPDATE t JOIN other ON … SET …; SQL Server UPDATE t SET … FROM t JOIN other ….

Step 2 Go further (free, optional)

Optional. The notes above are written to be enough on their own. These free resources give a second explanation and more practice.

Step 3 Practise

Try each one yourself first: out loud, or written and run in the practice box below, which saves every query you run. Then open the answer and compare.

  1. ExplainSay what it does and when to use it, in plain words, with no notes.

    Explain why you should run the WHERE as a SELECT before an UPDATE or DELETE.

    Show answer

    UPDATE and DELETE act on every row their WHERE matches, and there is no undo once it is committed. A WHERE that is slightly wrong (a typo, OR where you meant AND, a you forgot) can change far more rows than you meant, or none at all.

    Running the same WHERE as a SELECT first shows you exactly which rows will be hit and how many. If you expected 2 rows and see 2,000, you have just avoided a disaster. Then turn the SELECT into the UPDATE or DELETE, ideally inside a transaction, and check that the number of rows changed matches.

  2. Writefrom a blank page, then run it

    Give everyone in Engineering a 10% raise (whole pounds), then show their names and new salaries.

    Show answer

    Multiply by 110 and divide by 100. With whole numbers, the division drops any pence, which is what "whole pounds" asks for. The department is found by its name, so the query doesn't depend on remembering that Engineering is 1.

    sql
    UPDATE employees
    SET salary = salary * 110 / 100
    WHERE dept_id = (SELECT dept_id FROM departments WHERE dept_name = 'Engineering');
    SELECT name, salary
    FROM employees
    WHERE dept_id = 1
    ORDER BY name;

    4 rows

    namesalary
    Asha104500
    Ben77000
    Chen77000
    Hana88000
  3. Predictsay it before you run it

    How many rows does DELETE FROM order_items WHERE quantity >= 3; remove?

    Show answer

    7 rows: the item lines with a quantity of 3 or more. They are (101, headphones, 3), (103, mug, 5), (104, headphones, 5), (105, headphones, 3), (108, desk lamp, 3), (109, pen, 5) and (109, notebook, 4). 7 of the 14 remain.

    In SQLite, changes() reports how many rows the last statement changed.

    sql
    DELETE FROM order_items WHERE quantity >= 3;
    SELECT changes() AS rows_removed, (SELECT COUNT(*) FROM order_items) AS rows_left;

    1 row

    rows_removedrows_left
    77
  4. Edge casesSay what happens with NULLs, ties, duplicates or no rows at all, and fix it.

    Try DELETE FROM customers WHERE customer_id = 1;. What happens and why? What would have done?

    Show answer

    It fails: "FOREIGN KEY constraint failed". Priya (customer 1) has five orders, and each one's customer_id points at her. Deleting her would leave those orders pointing at nobody, so the database refuses, and nothing is deleted.

    With ON DELETE CASCADE on orders.customer_id, deleting Priya would also delete her five orders automatically. Those orders have 9 item lines in order_items, so that foreign key would need CASCADE too; otherwise it would still block the delete. One innocent-looking DELETE would remove 15 rows across three tables, which is why CASCADE should be a deliberate choice.

    sql
    DELETE FROM customers WHERE customer_id = 1;

    Error: FOREIGN KEY constraint failed

Practice box: write and run your answers here

Ctrl/⌘ + Enter runs it. Select part of the query to run only that part.

Step 4 Interview-ready, then prove it

Your interview answer

About 20 to 40 seconds, said out loud.

INSERT adds rows, ideally with an explicit column list; UPDATE changes columns in rows matched by WHERE, and DELETE removes matched rows. My safety habits are to run the WHERE as a SELECT first, wrap risky changes in a transaction so I can roll back, and use an upsert — insert on conflict do update — when a row may or may not exist, so it is a single atomic statement rather than a check-then-write race.

Follow-up questions

How would you safely delete a lot of rows?

Check the count with SELECT first, do it inside a transaction, and on very large tables delete in batches to avoid long locks.

Why is "check if it exists, then insert" a problem?

Two requests can both check, both see nothing, and both insert. An upsert or a constraint makes it atomic.

Tick each check when you can do it without notes

A topic is finished when you pass all four checks, not when you have read it. Be strict: if you had to look at the notes, it is not ticked yet.

  • Explain Say what it does and when to use it, in plain words, with no notes.
  • Write Write the query from a blank page, then run it to check.
  • Predict Read a query and say which rows it returns before you run it.
  • Edge cases Say what happens with NULLs, ties, duplicates or no rows at all, and fix it.

0 of 4 checks ticked.

Saved in this browser. Back it up or move it to another device.