MySQL
SQL update
conditional update
database management
SQL query

MySQL update field only if condition is met

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Conditional updates are one of the most important patterns in MySQL because they prevent stale writes and invalid state transitions. The safest place to enforce update conditions is inside SQL, not only in application code. When conditions and updates run in one statement, correctness is atomic.

Core Sections

Guarding State Transitions With WHERE

The baseline pattern is to update rows only when they are in the expected current state. This protects workflows such as payment status changes, order lifecycles, and job queues.

sql
1UPDATE orders
2SET status = 'shipped', shipped_at = NOW()
3WHERE id = 42
4  AND status = 'paid';

Immediately inspect changed rows:

sql
SELECT ROW_COUNT() AS changed_rows;

If changed_rows is 0, either the row does not exist or it is no longer in paid state. That makes retries safe because a second request does not reapply a transition that already happened.

For batch transitions, keep the condition explicit and indexable:

sql
1UPDATE jobs
2SET status = 'running', started_at = NOW()
3WHERE status = 'queued'
4  AND scheduled_at <= NOW()
5LIMIT 100;

This allows controlled throughput while maintaining business rules in SQL.

Conditional Column Values With CASE

Sometimes you always want to touch a row but only update one column when criteria match. CASE lets you encode this logic in a single, readable statement.

sql
1UPDATE accounts
2SET
3  credit_limit = CASE
4    WHEN risk_level = 'low' THEN credit_limit + 1000
5    WHEN risk_level = 'medium' THEN credit_limit + 250
6    ELSE credit_limit
7  END,
8  reviewed_at = NOW()
9WHERE id = 1001;

This avoids a read modify write round trip in application code. It is also easier to audit because the rule is centralized in one query instead of scattered across services.

A useful variant protects values from decreasing accidentally:

sql
1UPDATE products
2SET price = CASE
3  WHEN ? > price THEN ?
4  ELSE price
5END
6WHERE sku = ?;

With prepared statements, the same query can enforce monotonic updates in high traffic APIs.

Joining Conditions Across Tables and Concurrency Controls

Real business rules often depend on related records. Use UPDATE ... JOIN so selection and update happen atomically.

sql
1UPDATE inventory i
2JOIN purchase_orders p ON p.sku = i.sku
3SET i.restock_needed = 1
4WHERE p.expected_date <= CURDATE()
5  AND i.quantity < i.reorder_threshold;

When write races are possible, optimistic concurrency with a version column prevents silent overwrites.

sql
1UPDATE payments
2SET status = 'captured', version = version + 1, captured_at = NOW()
3WHERE payment_id = 'pay_123'
4  AND status = 'authorized'
5  AND version = 7;

Only one concurrent updater matches version 7. Losers get zero changed rows and can reload state.

For multi statement workflows, use transactions and row locks:

sql
1START TRANSACTION;
2
3SELECT balance
4FROM wallets
5WHERE user_id = 7
6FOR UPDATE;
7
8UPDATE wallets
9SET balance = balance - 50
10WHERE user_id = 7 AND balance >= 50;
11
12UPDATE wallets
13SET balance = balance + 50
14WHERE user_id = 19;
15
16COMMIT;

This pattern keeps dependent updates consistent even under concurrent requests.

Performance and Safety Checks Before Production

A conditional update can still be dangerous if the predicate is broad or unindexed. Validate with EXPLAIN and a dry run SELECT using the same filter.

sql
1EXPLAIN
2SELECT id
3FROM orders
4WHERE id = 42
5  AND status = 'paid';

Then run the real update inside a transaction in staging and verify row counts. Keeping this discipline prevents accidental large table modifications.

Common Pitfalls

  • Executing updates without restrictive predicates.
  • Checking conditions only in application code, then sending unconditional SQL.
  • Ignoring ROW_COUNT() and assuming every request changed data.
  • Missing indexes on predicate columns, causing wide lock scopes.
  • Splitting dependent updates across statements without a transaction.

Summary

  • Put update conditions in SQL so MySQL enforces them atomically.
  • Use WHERE guards for state transitions and CASE for column level logic.
  • Use UPDATE ... JOIN when rules depend on related tables.
  • Add optimistic version checks for high concurrency writes.
  • Validate predicates and plans before production execution.

Course illustration
Course illustration

All Rights Reserved.