Update Sql Server From Another Table

7 min read

Update SQL Server from Another Table: A Complete Guide to Synchronizing Data Efficiently

Keeping data consistent across related tables is a common requirement in database applications. Think about it: whether you need to refresh product prices, correct customer addresses, or propagate status flags, knowing how to update SQL Server from another table saves time, reduces manual errors, and ensures referential integrity. This article walks you through the most reliable techniques—UPDATE with JOIN, the MERGE statement, subqueries, and common table expressions (CTEs)—while highlighting performance tips, transaction safety, and best‑practice checks you can apply immediately.


Understanding the Core Concept

When you update SQL Server from another table, you are essentially telling the engine: take values from a source table (or query) and apply them to matching rows in a target table. The source can be a plain table, a filtered view, or even a derived result set. The key is to define a clear join condition that identifies which rows in the target correspond to which rows in the source.

SQL Server offers several syntaxes to achieve this:

Technique When to Use Main Advantage
UPDATE … FROM … JOIN Simple one‑to‑many or one‑to‑one updates Straightforward, readable
MERGE Complex upserts (insert‑update‑delete) in a single statement Atomic, handles multiple actions
Subquery in SET clause When you need a scalar value per row Minimal changes to existing UPDATE
CTE‑based UPDATE When you need to pre‑aggregate or filter source data Improves readability and reuse

Each method follows the same logical steps: identify matching rows, compute new values, and apply the change within a transaction (if desired).


1. UPDATE with JOIN – The Most Common Approach

The UPDATE … FROM … JOIN pattern lets you reference the source table directly in the FROM clause and join it to the target table That alone is useful..

Syntax

UPDATE t
SET    t.Column1 = s.ColumnA,
       t.Column2 = s.ColumnB
FROM   TargetTable AS t
INNER JOIN SourceTable AS s
        ON t.KeyColumn = s.KeyColumn
WHERE  t.SomeCondition = 1   -- optional filter

Example: Updating Product Prices

Suppose you have a Products table that stores current prices and a PriceUpdates table that receives nightly price feeds The details matter here..

-- Target: Products
-- Source: PriceUpdates
UPDATE p
SET    p.ListPrice = u.NewPrice,
       p.LastUpdated = GETDATE()
FROM   Products AS p
INNER JOIN PriceUpdates AS u
        ON p.ProductID = u.ProductID
WHERE  u.EffectiveDate = (SELECT MAX(EffectiveDate)
                          FROM PriceUpdates
                          WHERE ProductID = p.ProductID);

Why this works:

  • The INNER JOIN ensures only products with a matching feed row are touched.
  • The WHERE clause inside the sub‑select guarantees you use the latest feed entry per product.
  • SET can modify multiple columns at once.

Performance Tips

  1. Index the join columns (ProductID in both tables) to avoid costly scans.
  2. Filter early – if you know only a subset of rows needs updating, add a WHERE clause on the target table before the join.
  3. Consider a temporary table for large source datasets; materializing the feed once can reduce repeated reads.

2. Using MERGE for Upsert‑Style Updates

When you need to insert new rows, update existing ones, or even delete obsolete records based on the source, the MERGE statement provides a single, atomic solution Easy to understand, harder to ignore..

Syntax

MERGE TargetTable AS tgt
USING SourceTable AS src
    ON tgt.KeyColumn = src.KeyColumn
WHEN MATCHED THEN
    UPDATE SET tgt.Column1 = src.ColumnA,
               tgt.Column2 = src.ColumnB
WHEN NOT MATCHED BY TARGET THEN
    INSERT (KeyColumn, Column1, Column2)
    VALUES (src.KeyColumn, src.ColumnA, src.ColumnB)
WHEN NOT MATCHED BY SOURCE THEN
    DELETE;   -- optional: remove rows that no longer exist in source

Example: Synchronizing Employee Records

MERGE Employees AS e
USING StagingEmployees AS se
    ON e.EmployeeID = se.EmployeeID
WHEN MATCHED AND (e.Name <> se.Name OR e.Department <> se.Dept) THEN
    UPDATE SET e.Name = se.Name,
               e.Department = se.Dept,
               e.LastSync = GETDATE()
WHEN NOT MATCHED BY TARGET THEN
    INSERT (EmployeeID, Name, Department, HireDate, LastSync)
    VALUES (se.EmployeeID, se.Name, se.Dept, se.HireDate, GETDATE())
WHEN NOT MATCHED BY SOURCE THEN
    DELETE;

Advantages:

  • All three actions (update, insert, delete) occur in one pass, reducing lock duration.
  • The OUTPUT clause can capture what happened to each row for auditing.

Caveats

  • MERGE can be harder to debug; test with a small dataset first.
  • Ensure proper indexing on the join key (EmployeeID) to avoid full table scans.
  • If you only need updates, the simpler UPDATE … FROM is often clearer.

3. Subquery in the SET Clause

Sometimes you only need a single scalar value from another table (e.In practice, g. , a lookup). A correlated subquery works well here Practical, not theoretical..

Syntax

UPDATE TargetTable
SET    ColumnX = (SELECT s.Value
                  FROM   SourceTable s
                  WHERE  s.Key = TargetTable.ForeignKey
                  -- optional additional filters
                 )
WHERE  EXISTS (SELECT 1
               FROM   SourceTable s
               WHERE  s.Key = TargetTable.ForeignKey);

Example: Setting a Default Tax Rate

UPDATE Orders
SET    TaxRate = (SELECT r.Rate
                  FROM   TaxRates r
                  WHERE  r.State = Orders.ShipToState
                         AND r.EffectiveDate = (SELECT MAX(EffectiveDate)
                                                FROM TaxRates
                                                WHERE State = Orders.ShipToState))
WHERE  EXISTS (SELECT 1
               FROM   TaxRates r
               WHERE  r.State = Orders.ShipToState);

When to Choose This:

  • The source returns at most one row per target row (guaranteed by a unique key or aggregation).
  • You want to keep the UPDATE statement compact without adding a FROM clause.

Performance Note:
Correlated subqueries can become expensive if the source table lacks an index on the join column

4. Using a Derived Table (JOIN) in the SET Clause

When the source data is more complex than a single‑row lookup, a JOIN inside the UPDATE statement often provides the clearest solution. This pattern lets you pull multiple columns from a related table (or even another derived set) and apply them directly to the target rows.

Syntax

UPDATE  t
SET     col1 = s.col1,
        col2 = s.col2,
        col3 = s.col3
FROM    TargetTable AS t
JOIN    SourceTable   AS s
        ON s.Key = t.ForeignKey        -- join condition
WHERE   s.SomeFlag = 1;                -- optional filter on source

Example: Enriching Product Prices with a Discount Table

-- Target: the production inventory table
UPDATE  p
SET     ListPrice      = d.NewPrice,
        DiscountPct   = d.Discount,
        PriceUpdated   = GETDATE()
FROM    Products AS p
JOIN    DiscountMap AS d
        ON d.ProductID = p.ProductID
WHERE   d.EffectiveDate = (SELECT MAX(EffectiveDate)
                           FROM DiscountMap dm
                           WHERE dm.ProductID = p.ProductID);

Explanation – The JOIN pulls the most recent discount information for each product and updates the price columns in a single pass. Because the join is performed on the indexed ProductID, the operation can be parallelized and typically runs faster than a correlated subquery Still holds up..

When to Prefer This Approach

  • The source contains multiple columns you need to copy.
  • You need aggregation (e.g., MAX, MIN) before applying values.
  • You want to filter the source rows based on additional criteria that are easier to express in a WHERE clause on the join.

5. Leveraging the OUTPUT Clause for Auditing

SQL Server’s OUTPUT clause lets you capture the changes made by an UPDATE, INSERT, or DELETE without spawning separate triggers. This is invaluable for audit trails, change‑data capture, or feeding a staging table.

Basic Pattern

UPDATE  t
SET     SomeColumn = NEWVALUE
OUTPUT  DELETED.SomeColumn AS OldValue,
        INSERTED.SomeColumn AS NewValue,
        CURRENT_TIMESTAMP AS ChangeDate
INTO    ChangeLog (OldValue, NewValue, ChangeDate)
WHERE   t.Key = @Key;

Key points

  • DELETED represents the row as it existed before the modification.
  • INSERTED represents the row as it will exist after the modification (for UPDATE only).
  • The INTO target can be a table, view, or table‑valued parameter.

Example: Synchronizing a Lookup Table

MERGE LookupTarget AS t
USING StagingLookup AS s
ON t.Code = s.Code
WHEN MATCHED AND t.Description <> s.Description THEN
    UPDATE SET t.Description = s.Description
    OUTPUT    'UPDATE'        AS Action,
              t.Code          AS Code,
              DELETED.Description AS OldDesc,
              INSERTED.Description AS NewDesc,
              CURRENT_TIMESTAMP    AS ChangeDate
    INTO    AuditLog (Action, Code, OldDescription, NewDescription, ChangeDate);
WHEN NOT MATCHED BY TARGET THEN
    INSERT (Code, Description, EffectiveDate)
    VALUES (s.Code, s.Description, GETDATE())
    OUTPUT    'INSERT'        AS Action,
              INSERTED.Code   AS Code,
              NULL            AS OldDescription,
              INSERTED.Description AS NewDescription,
              CURRENT_TIMESTAMP    AS ChangeDate
    INTO    AuditLog (Action, Code, OldDescription, NewDescription, ChangeDate);
WHEN NOT MATCHED BY SOURCE THEN
    DELETE
    OUTPUT    'DELETE'        AS Action,
              DELETED.Code    AS Code,
              DELETED.Description AS OldDescription,
              NULL            AS NewDescription,
              CURRENT_TIMESTAMP    AS ChangeDate
    INTO    AuditLog (Action, Code, OldDescription, NewDescription, ChangeDate);

Result – Every insert, update, or delete performed by the MERGE is logged to AuditLog with a timestamp and the before/after values, all in a single batch.


6. Performance Tips & Common Pitfalls

Issue Why It Hurts Mitigation
Missing index on join column
Just Hit the Blog

New Today

You Might Find Useful

Based on What You Read

Thank you for reading about Update Sql Server From Another Table. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home