SQL Quest

Lessons, hints, explained solutions, the in-browser PostgreSQL editor and practice answer checks in your browser are available. Graded assessments, recorded progress from answer checks and new certificates aren't available yet.

UPDATE

Changes column values in the rows that match a condition.

Syntax

UPDATE table [AS t]
SET col1 = expr1, col2 = expr2
[FROM other_table]
[WHERE condition]
[RETURNING ...];
  • Without WHERE, every row is updated. Run the same WHERE as a SELECT first to see which rows will change, and use a transaction when in doubt.
  • Expressions on the right see the old values of the row: SET a = b, b = a swaps them.
  • UPDATE ... FROM other joins another table to compute new values or restrict rows. Each target row should match at most one row of other; if several match, one is used unpredictably.
  • SET col = DEFAULT restores the default; SET col = NULL clears it.
  • Constraints are checked: a CHECK or foreign-key violation aborts the whole statement.
  • RETURNING shows the updated rows; in PostgreSQL 18 RETURNING old.col, new.col shows before and after.

Examples

Price increase for one category (modifies data) starter
UPDATE products
SET price = round(price * 1.05, 2)
WHERE category = 'Kitchen'
RETURNING product_id, product_name, old.price AS old_price, new.price AS new_price;

Only Kitchen products change; RETURNING old/new (PostgreSQL 18) shows before and after.

UPDATE with FROM (modifies data) starter
UPDATE products p
SET stock = p.stock - s.units
FROM (SELECT product_id, sum(quantity) AS units
      FROM orders WHERE status = 'processing'
      GROUP BY product_id) s
WHERE s.product_id = p.product_id
  AND p.stock >= s.units
RETURNING p.product_id, p.stock;

Aggregate first so each product matches exactly one row of s.

Pitfalls

  • Forgetting WHERE (updates every row).

  • UPDATE ... FROM where the joined table has several matching rows per target row (non-deterministic result).

  • Comparing with = NULL in the WHERE clause (matches nothing).

  • Repeating the target table in FROM (UPDATE t ... FROM t creates a self-join over every row).

Other databases

For orientation only: SQL Quest executes PostgreSQL.

SQL Server

UPDATE t SET ... FROM t JOIN other ...; OUTPUT deleted.col, inserted.col for before/after.

MySQL

Multi-table form: UPDATE t JOIN other ON ... SET ...; supports ORDER BY and LIMIT on single-table UPDATE.