SQL
data manipulation
database
SQL update
database management

Copy values from one column to another in the same table

Master System Design with Codemia

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

Introduction

Copying data from one column to another in the same table is a common migration task, but the risk is usually operational rather than syntactic. A single unscoped update can overwrite trusted values or lock a hot table for too long. A safe approach is to preview affected rows, apply guarded updates, verify outcomes, and only then finalize constraints.

Basic Update Pattern

The core statement is simple:

sql
UPDATE employees
SET backup_email = email;

This copies email into backup_email for every row. It is correct for full-table backfill, but in production most updates should be narrowed with explicit conditions.

A safer first version is:

sql
1UPDATE employees
2SET backup_email = email
3WHERE backup_email IS NULL
4  AND email IS NOT NULL;

This avoids overwriting existing values and makes retries idempotent.

Preview and Count Before Updating

Before changing data, preview representative rows and count impact. These two checks catch most filter mistakes.

sql
1SELECT id, email, backup_email
2FROM employees
3WHERE backup_email IS NULL
4  AND email IS NOT NULL
5ORDER BY id
6LIMIT 20;
sql
1SELECT COUNT(*) AS rows_to_update
2FROM employees
3WHERE backup_email IS NULL
4  AND email IS NOT NULL;

If the count is unexpectedly large, stop and re-check predicates. Never treat a mass update as harmless just because the query is short.

Use Transactions for Safety

Wrap the operation in a transaction when your engine and workload allow it.

sql
1BEGIN;
2
3UPDATE employees
4SET backup_email = email
5WHERE backup_email IS NULL
6  AND email IS NOT NULL;
7
8SELECT COUNT(*) AS still_missing
9FROM employees
10WHERE backup_email IS NULL
11  AND email IS NOT NULL;
12
13COMMIT;

If validation fails, run ROLLBACK instead of commit. This gives you a clean escape hatch during migrations.

Copy with Transformation

Sometimes the destination column has different format requirements. You can transform in the same update as long as the transformation is deterministic and reviewed.

sql
1UPDATE users
2SET username_normalized = LOWER(TRIM(username))
3WHERE username IS NOT NULL
4  AND username_normalized IS NULL;

Another common case is explicit casting between numeric and text columns:

sql
1UPDATE metrics
2SET value_text = CAST(value_num AS VARCHAR(32))
3WHERE value_num IS NOT NULL
4  AND value_text IS NULL;

Avoid relying on implicit conversion when portability matters.

Large Tables and Batch Backfill

On large tables, one giant update can hold locks too long or create replication lag. Batch by key range or timestamp window.

sql
1UPDATE events
2SET archived_payload = payload
3WHERE id >= 1 AND id < 50001
4  AND archived_payload IS NULL;

Then repeat with the next range. Between batches, monitor lock waits, query latency, and replica delay. Batching is slower in wall-clock time but safer for live systems.

A practical rollout pattern:

  1. Add new nullable column.
  2. Backfill in batches.
  3. Verify no missing values.
  4. Switch reads and writes to new column.
  5. Add NOT NULL or default constraints.

This staged method is easier to recover than one all-in migration.

Database-Specific Notes

The SQL pattern is universal, but behavior differs by engine.

  • PostgreSQL can return changed rows via RETURNING for auditing.
  • SQL Server might need careful indexing to avoid lock escalation on large updates.
  • MySQL behavior can vary with storage engine and transaction settings.

If your update must run online, test on staging with production-like row counts and indexes.

Validate After the Update

Do not stop at affected-row count from the update command. Run targeted checks.

sql
1SELECT COUNT(*) AS mismatch_count
2FROM employees
3WHERE email IS NOT NULL
4  AND backup_email IS DISTINCT FROM email;

For engines without IS DISTINCT FROM, use explicit null-aware checks. Also spot-check a sample by primary key and record the migration id in an operations log.

Common Pitfalls

The most frequent failure is forgetting a WHERE clause and updating the entire table accidentally. Another is overwriting curated target values because the query did not include target_column IS NULL. Teams also run into long lock windows by executing one huge update on hot tables instead of batching. A less obvious issue is silent type coercion, where copied values are truncated or reformatted unexpectedly. Finally, skipping post-update validation makes rollback decisions blind.

Summary

  • Use UPDATE ... SET target = source as the base pattern, then add strict predicates.
  • Preview rows and count impact before making changes.
  • Run updates in transactions and validate before commit.
  • Batch large backfills to reduce operational risk.
  • Validate data correctness after update, not only affected-row counts.

Course illustration
Course illustration

All Rights Reserved.