- Learn
- PostgreSQL
- PostgreSQL UPDATE
PostgreSQL UPDATE
Update single rows, multiple rows, and use RETURNING to get the changed data back.
Basic syntax
The WHERE clause is optional, but leaving it out updates every row in the table. Always double-check your WHERE clause before running an UPDATE.
Updating a single row
Target a specific row by its primary key:
Filtering on the primary key guarantees you're changing exactly one row.
Updating multiple rows
Any rows matching the WHERE condition will be updated. This example marks all peripherals as inactive:
Updating multiple columns
List each column assignment separated by commas inside SET:
UPDATE with expressions
You can reference the current column value in the SET expression. This is useful for incrementing counters, applying discounts, or transforming text.
UPDATE ... FROM (PostgreSQL-specific)
PostgreSQL extends the standard UPDATE syntax with a FROM clause, which lets you join another table and use its values in the update. This is PostgreSQL-specific syntax and will not work in SQLite.
A more practical example: update order totals based on a separate shipping fees table.
The FROM clause works like a JOIN. You can reference columns from the joined table in both SET and WHERE.
UPDATE with subquery in WHERE
Use a subquery to update rows based on data from another table:
The subquery runs first and returns a set of IDs. The outer UPDATE then applies to only those rows.
RETURNING clause
RETURNING makes UPDATE return the affected rows, similar to a SELECT. This is useful when you need the updated values without running a second query.
You can return any column, including ones you didn't change:
RETURNING * returns all columns.
Note: RETURNING is PostgreSQL-specific. It is not standard SQL and is not available in MySQL. SQLite supports it from version 3.35 (2021).
The "update all rows" danger
UPDATE without a WHERE clause changes every row in the table:
This is rarely what you want. Before running any UPDATE, check what rows you're targeting by running the equivalent SELECT first:
If you're working in production, wrap the UPDATE in a transaction so you can roll it back if something looks wrong:
Checking affected rows
PostgreSQL reports the number of rows updated after each UPDATE statement:
UPDATE 5
In application code, the row count is available through your database driver. In psql, you see it directly in the output.
The RETURNING clause is useful when you need more than a count. For example, after updating an order status, you might want to return the order ID and timestamp to confirm which rows changed:
If RETURNING gives back zero rows, no rows matched the WHERE condition.
Common errors
NOT NULL violation
ERROR: null value in column "name" of relation "products" violates not-null constraint
You tried to set a NOT NULL column to NULL. Check your SET clause and confirm the value you're assigning is not null.
Unique constraint violation
ERROR: duplicate key value violates unique constraint "products_sku_key"
The new value conflicts with an existing row. Either find the conflicting row first, or use ON CONFLICT with an INSERT ... ON CONFLICT DO UPDATE (upsert) pattern instead.
Type mismatch
ERROR: invalid input syntax for type integer: "twenty"
The value you're assigning doesn't match the column's data type. Cast explicitly if needed:
Quick reference
| Syntax | Description |
|--------|-------------|
| UPDATE t SET col = val WHERE ... | Basic update |
| UPDATE t SET col1 = v1, col2 = v2 WHERE ... | Update multiple columns |
| UPDATE t SET col = col + 1 WHERE ... | Update using an expression |
| UPDATE t SET col = val FROM other WHERE ... | Update using a joined table (PostgreSQL) |
| UPDATE t SET col = val WHERE id IN (SELECT ...) | Update using a subquery |
| UPDATE t SET col = val WHERE ... RETURNING * | Return updated rows |
| UPDATE t SET col = val | Update all rows (use with caution) |