How can I do an UPDATE statement with JOIN in SQL Server?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
SQL Server supports UPDATE ... FROM ... JOIN syntax to update rows in one table based on values from another table. This is a T-SQL extension not available in standard SQL. The key is that the UPDATE target references the table alias from the FROM clause, and the JOIN provides the matching condition. Other databases (MySQL, PostgreSQL) have different syntax for the same operation.
Basic Syntax
The UPDATE a tells SQL Server which table to modify. The FROM clause with JOIN brings in the source data.
Example: Update Orders from Customers
This updates every order from 2025 onwards with the current customer name and email from the Customers table.
LEFT JOIN — Update with Optional Match
With LEFT JOIN, rows in Orders without a matching promotion still get updated — p.DiscountPercent is NULL for non-matches, and COALESCE converts it to 0.
Multiple Joins
You can join as many tables as needed. The WHERE clause filters which rows get updated.
UPDATE with Subquery (Alternative)
This achieves the same result but is less readable for complex multi-table updates. The EXISTS check prevents setting CustomerName to NULL for orders without matching customers.
UPDATE with CTE
CTEs make complex update logic more readable. The CTE acts as a view that you update directly.
UPDATE with OUTPUT (Audit Trail)
The OUTPUT clause captures before and after values for auditing.
MERGE Statement (Upsert)
For insert-or-update operations, use MERGE:
Cross-Database Syntax Comparison
Each database has different syntax. SQL Server and MySQL put JOIN in different positions.
Performance Tips
Batch updates prevent long-running transactions that lock the table.
Common Pitfalls
- Ambiguous table in UPDATE:
UPDATE Orders SET ...without aFROMclause updates based on the table directly. AddingFROM Orders JOIN ...creates a second reference to Orders. Use an alias:UPDATE o SET ... FROM Orders AS o JOIN .... - Multiple matches: If the JOIN produces multiple matching rows in the source table, SQL Server picks one arbitrarily. The result is non-deterministic. Use
ROW_NUMBER()orTOP 1in a subquery to ensure one match per target row. - Missing WHERE clause: An
UPDATE ... JOINwithoutWHEREupdates every matching row. Always verify with aSELECTusing the sameFROM/JOIN/WHEREbefore running theUPDATE. - Deadlocks on large updates: Updating millions of rows in a single transaction acquires many locks and can deadlock with concurrent operations. Use batch updates with
TOP (n)in a loop. - Not testing with SELECT first: Replace
UPDATE a SET ...withSELECT a.*, b.*using the sameFROM/JOIN/WHEREto preview which rows will be affected before executing the update.
Summary
- Use
UPDATE alias SET ... FROM table AS alias JOIN ...syntax in SQL Server - The
UPDATEtarget uses the alias defined in theFROMclause LEFT JOINupdates allow handling missing matches withCOALESCE- CTEs and
OUTPUTclauses make complex updates readable and auditable - Always preview with
SELECTbefore runningUPDATEto verify affected rows - Batch large updates with
TOP (n)in a loop to avoid lock escalation

