Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

In SQL Server you can insert into a table using a select statement:

INSERT INTO table(col,col2,col3)
SELECT col,col2,col3 FROM other_table WHERE sql = 'cool'

How can I update via a select as well in a similar manner? I have a temporary table that has the values, and I want to update another table using those values.

Something like this:

UPDATE Table SET col1,col2
SELECT col1,col2 FROM other_table WHERE sql = 'cool'
WHERE Table.id = other_table.id
share|improve this question

12 Answers

up vote 733 down vote accepted
UPDATE
    Table
SET
    Table.col1 = other_table.col1,
    Table.col2 = other_table.col2
FROM
    Table
INNER JOIN
    other_table
ON
    Table.id = other_table.id
share|improve this answer
1  
Sweeeeeeeeeet, thx! – Shredder Apr 11 '11 at 17:52
8  
OMG! I forgot the WHERE clause. Already fixed it. – Nelson Reis Sep 13 '11 at 9:55
1  
@RodrigoGama - Why doesn't it? I'm using it with a variable table fine. – Omar Jan 19 '12 at 15:34
24  
'Table' is once used as name of the table and than as an alias. This is confusing. Maybe "Table t" would be better.. – Filip May 24 '12 at 17:05
35  
Turns out I already upvoted this. I keep coming back here as I can never remember the syntax. – Ben Challenor Oct 24 '12 at 14:20
show 6 more comments

In SQL Server 2008 (or better), use MERGE

MERGE INTO Table
   USING (
          SELECT id, col1, col2 
            FROM other_table 
           WHERE sql = 'cool'
         ) AS source
      ON Table.id = source.id
WHEN MATCHED THEN
   UPDATE 
      SET col1 = source.col1, 
          col2 = source.col2;
share|improve this answer
2  
Had not heard about this keyword yet, but it worked like a charm for me. Thanks! – Matt McHugh Feb 15 '12 at 22:19
13  
MERGE can also be used for "Upserting" records; that is, UPDATE if matching record exists, INSERT new record if no match found – brichins May 15 '12 at 19:51
2  
This was around 10x quicker than the equivalent update...join statement for me. – Paul Suart Apr 3 at 2:49

I'd modify Robin's excellent answer to the following:

UPDATE
     Table 
SET
     Table.col1 = other_table.col1,
     Table.col2 = other_table.col2 
FROM
     Table 
INNER JOIN     
     other_table 
ON     
     Table.id = other_table.id 
WHERE
     Table.col1 != other_table.col1 or 
     Table.col2 != other_table.col2 or
     (other_table.col1 is not null and table.col1 is null) or
     (other_table.col2 is not null and table.col2 is null)

Without a WHERE clause, you'll affect even rows that don't need to be affected, which could (possibly) cause index recalculation or fire triggers that really shouldn't have been fired.

share|improve this answer
This assumes none of the columns are nullable though. – Martin Smith Nov 6 '11 at 0:03
   
You're right, I was typing the example by hand. I've added a third and fourth clause to the where statement to deal with that. – quillbreaker Nov 11 '11 at 20:27
6  
WHERE EXISTS(SELECT T1.Col1, T1.Col2 EXCEPT SELECT T2.Col1, T2.Col2)) is more concise. – Martin Smith May 27 '12 at 9:44
1  
shouldn't the statement also contain these two in the where clause? (other_table.col1 is null and table.col1 is not null) or (other_table.col2 is null and table.col2 is not null) – user277498 May 15 at 4:03
1  
Depends on if you want to replace nulls in the destination with nulls from the source. Frequently, I don't. But if you do, Martin's construction of the where clause is the best thing to use. – quillbreaker May 16 at 16:35
show 1 more comment

One way

UPDATE t SET  t.col1 = o.col1,
t.col2 = o.col2
FROM other_table o 
join t on t.id = o.id
WHERE o.sql = 'cool'
share|improve this answer

Another possibility not mentioned yet is to just chuck the SELECT statement itself into a CTE then Update the CTE.

;WITH CTE
     AS (SELECT T1.Col1,
                T2.Col1 AS _Col1,
                T1.Col2,
                T2.Col2 AS _Col2
         FROM   T1
                JOIN T2
                  ON T1.id = T2.id
         /*Where clause added to exclude rows that are the same in both tables
           Handles NULL values correctly*/
         WHERE EXISTS(SELECT T1.Col1,
                             T1.Col2
                       EXCEPT
                       SELECT T2.Col1,
                              T2.Col2))
UPDATE CTE
SET    Col1 = _Col1,
       Col2 = _Col2  

This has the benefit that it is easy to run the SELECT statement on its own first to sanity check the results but it does requires you to alias the columns as above if they are named the same in source and target tables.

This also has the same limitation as the proprietary UPDATE ... FROM syntax shown in four of the other answers. If the source table is on the many side of a one to many join then it is undeterministic which of the possible matching joined records will be used in the Update (An issue that MERGE avoids by raising an error if there is an attempt to update the same row more than once).

share|improve this answer
is there any meaning of the name CTE ? – Shivan Raptor Oct 8 '12 at 12:48
2  
@ShivanRaptor - It is the acronym for Common Table Expression. Just an arbitrary alias in this case. – Martin Smith Oct 8 '12 at 13:05
UPDATE Table SET Col1=i.Col1 ,
Col2=i.Col2 FROM (SELECT Col1,Col2 FROM  other_table)i
where i.ID=Table.ID
share|improve this answer

Using alias:

UPDATE t
   SET t.col1 = o.col1
  FROM table1 AS t
         INNER JOIN 
       table2 AS o 
         ON t.id = o.id
share|improve this answer

This may be a niche reason to perform an update (for example, mainly used in a procedure), or may be obvious to others, but it should also be stated that you can perform an update-select statement without using join (in case the tables you're updating between have no common field).

update
    Table
set
    Table.example = a.value
from
    TableExample a
where
    Table.field = *key value* -- finds the row in Table 
    AND a.field = *key value* -- finds the row in TableExample a
share|improve this answer

For the record (and others searching like I was), you can do it in MySQL like this:

UPDATE first_table, second_table
SET first_table.color = second_table.color
WHERE first_table.id = second_table.foreign_id
share|improve this answer

The sample way to do it is:

UPDATE
    table_to_update,
    table_info
SET
    table_to_update.col1 = table_info.col1,
    table_to_update.col2 = table_info.col2

WHERE
    table_to_update.ID = table_info.ID
share|improve this answer
1  
Yours is formatted better; Also, when using a subselect, yours (and Adrian's) work more reliably than the other format. Thanks for posting your answer. – Ben West Feb 14 at 22:11
This is not SQl Server syntax and it will not work in SQL server – HLGEM Apr 24 at 18:32

I add this only so you can see a quick way to write it so that you can check what will be updated before doing the update.

UPDATE Table 
SET  Table.col1 = other_table.col1,
     Table.col2 = other_table.col2 
--select Table.col1, other_table.col,Table.col2,other_table.col2, *   
FROM     Table 
INNER JOIN     other_table 
    ON     Table.id = other_table.id 
share|improve this answer

here is another useful syntax:

UPDATE suppliers
SET supplier_name = (SELECT customers.name
                     FROM customers
                     WHERE customers.customer_id = suppliers.supplier_id)
WHERE EXISTS (SELECT customers.name
              FROM customers
              WHERE customers.customer_id = suppliers.supplier_id);

it checks if it is null or not by using "WHERE EXIST"

share|improve this answer

protected by Mr. Alien Apr 11 at 8:51

This question is protected to prevent "thanks!", "me too!", or spam answers by new users. To answer it, you must have earned at least 10 reputation on this site.

Not the answer you're looking for? Browse other questions tagged or ask your own question.