How can I do an UPDATE statement with JOIN in SQL Server?

SqlSql ServerTsqlSql Server-2005Sql Update

Sql Problem Overview


I need to update this table in SQL Server with data from its 'parent' table, see below:

Table: sale

id (int)
udid (int)
assid (int)

Table: ud

id  (int)
assid  (int)

sale.assid contains the correct value to update ud.assid.

What query will do this? I'm thinking of a join but I'm not sure if it's possible.

Sql Solutions


Solution 1 - Sql

Syntax strictly depends on which SQL DBMS you're using. Here are some ways to do it in ANSI/ISO (aka should work on any SQL DBMS), MySQL, SQL Server, and Oracle. Be advised that my suggested ANSI/ISO method will typically be much slower than the other two methods, but if you're using a SQL DBMS other than MySQL, SQL Server, or Oracle, then it may be the only way to go (e.g. if your SQL DBMS doesn't support MERGE):

ANSI/ISO:

update ud 
     set assid = (
          select sale.assid 
          from sale 
          where sale.udid = ud.id
     )
 where exists (
      select * 
      from sale 
      where sale.udid = ud.id
 );

MySQL:

update ud u
inner join sale s on
    u.id = s.udid
set u.assid = s.assid

SQL Server:

update u
set u.assid = s.assid
from ud u
    inner join sale s on
        u.id = s.udid

PostgreSQL:

update ud
  set assid = s.assid
from sale s 
where ud.id = s.udid;

Note that the target table must not be repeated in the FROM clause for Postgres.

Oracle:

update
    (select
        u.assid as new_assid,
        s.assid as old_assid
    from ud u
        inner join sale s on
            u.id = s.udid) up
set up.new_assid = up.old_assid

SQLite:

update ud 
     set assid = (
          select sale.assid 
          from sale 
          where sale.udid = ud.id
     )
 where RowID in (
      select RowID 
      from ud 
      where sale.udid = ud.id
 );

Solution 2 - Sql

This should work in SQL Server:

update ud 
set assid = sale.assid
from sale
where sale.udid = id

Solution 3 - Sql

postgres

UPDATE table1
SET    COLUMN = value
FROM   table2,
	   table3
WHERE  table1.column_id = table2.id
	   AND table1.column_id = table3.id
	   AND table1.COLUMN = value
	   AND table2.COLUMN = value
	   AND table3.COLUMN = value 

Solution 4 - Sql

A standard SQL approach would be

UPDATE ud
SET assid = (SELECT assid FROM sale s WHERE ud.id=s.id)

On SQL Server you can use a join

UPDATE ud
SET assid = s.assid
FROM ud u
JOIN sale s ON u.id=s.id

Solution 5 - Sql

PostgreSQL:

CREATE TABLE ud (id integer, assid integer);
CREATE TABLE sales (id integer, udid integer, assid integer);

UPDATE ud
SET assid = sales.assid
FROM sales
WHERE sales.id = ud.id;

Solution 6 - Sql

Simplified update query using JOIN-ing multiple tables.

   UPDATE
        first_table ft
        JOIN second_table st ON st.some_id = ft.some_id
        JOIN third_table tt  ON tt.some_id = st.some_id
        .....
    SET
        ft.some_column = some_value
    WHERE ft.some_column = 123456 AND st.some_column = 123456

Note - first_table, second_table, third_table and some_column like 123456 are demo table names, column names and ids. Replace them with the valid names.

Solution 7 - Sql

Another example why SQL isn't really portable.

For MySQL it would be:

update ud, sale
set ud.assid = sale.assid
where sale.udid = ud.id;

For more info read multiple table update: http://dev.mysql.com/doc/refman/5.0/en/update.html

UPDATE [LOW_PRIORITY] [IGNORE] table_references
    SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
    [WHERE where_condition]

Solution 8 - Sql

Teradata Aster offers another interesting way how to achieve the goal:

MERGE INTO ud --what table should be updated
USING sale -- from what table/relation update info should be taken
ON ud.id = sale.udid --join condition
WHEN MATCHED THEN 
	UPDATE SET ud.assid = sale.assid; -- how to update

Solution 9 - Sql

I was thinking the SQL-Server one in the top post would work for Sybase since they are both T-SQL but unfortunately not.

For Sybase I found the update needs to be on the table itself not the alias:

update ud
set u.assid = s.assid
from ud u
    inner join sale s on
	    u.id = s.udid

Solution 10 - Sql

MySQL

You'll get the best performance if you forget the where clause and place all conditions in the ON expression.

I think this is because the query first has to join the tables then runs the where clause on that, so if you can reduce what is required to join then that's the fasted way to get the results/do the udpate.

Example

Scenario

You have a table of users. They can log in using their username or email or account_number. These accounts can be active (1) or inactive (0). This table has 50000 rows

You then have a table of users to disable at one go because you find out they've all done something bad. This table however, has one column with usernames, emails and account numbers mixed. It also has a "has_run" indicator which needs to be set to 1 (true) when it has been run

Query
UPDATE users User
    INNER JOIN
        blacklist_users BlacklistUser
        ON
        (
            User.username = BlacklistUser.account_ref
            OR
            User.email = BlacklistedUser.account_ref
            OR
            User.phone_number = BlacklistUser.account_ref
            AND
            User.is_active = 1
            AND
            BlacklistUser.has_run = 0
        )
    SET
        User.is_active = 0,
        BlacklistUser.has_run = 1;
Reasoning

If we had to join on just the OR conditions it would essentially need to check each row 4 times to see if it should join, and potentially return a lot more rows. However, by giving it more conditions it can "skip" a lot of rows if they don't meet all the conditions when joining.

Bonus

It's more readable. All the conditions are in one place and the rows to update are in one place

Solution 11 - Sql

The following statement with FROM keyword is used to update multiple rows with a join

UPDATE users 
set users.DivisionId=divisions.DivisionId
from divisions join users on divisions.Name=users.Division

Solution 12 - Sql

The simplest way is to use the Common Table Expression (CTE) introduced in SQL 2005

with cte as
(select u.assid col1 ,s.assid col2 from ud u inner join sale s on u.id = s.udid)
update cte set col1=col2

Solution 13 - Sql

And in MS ACCESS:

UPDATE ud 
INNER JOIN sale ON ud.id = sale.udid
SET ud.assid = sale.assid;

Solution 14 - Sql

Try this one, I think this will works for you

update ud

set ud.assid = sale.assid

from ud 

Inner join sale on ud.id = sale.udid

where sale.udid is not null

Solution 15 - Sql

UPDATE tblAppraisalBasicData
SET tblAppraisalBasicData.ISCbo=1
FROM tblAppraisalBasicData SI INNER JOIN  aaa_test RAN ON SI.EmpID = RAN.ID

Solution 16 - Sql

For SQLite use the RowID property to make the update:

update Table set column = 'NewValue'
where RowID = 
(select t1.RowID from Table t1
join Table2 t2 on t1.JoinField = t2.JoinField
where t2.SelectValue = 'FooMyBarPlease');

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnt SwiftView Question on Stackoverflow
Solution 1 - SqlEricView Answer on Stackoverflow
Solution 2 - SqledosoftView Answer on Stackoverflow
Solution 3 - Sqluser1154043View Answer on Stackoverflow
Solution 4 - SqlMattHView Answer on Stackoverflow
Solution 5 - SqlalfonxView Answer on Stackoverflow
Solution 6 - SqlVinit KadkolView Answer on Stackoverflow
Solution 7 - SqlYadaView Answer on Stackoverflow
Solution 8 - SqlxhudikView Answer on Stackoverflow
Solution 9 - SqlKen GohView Answer on Stackoverflow
Solution 10 - SqlLuke WattsView Answer on Stackoverflow
Solution 11 - SqlSheryar NizarView Answer on Stackoverflow
Solution 12 - SqlKemal AL GAZZAHView Answer on Stackoverflow
Solution 13 - SqlRichardView Answer on Stackoverflow
Solution 14 - SqlHARSHIT RATHOREView Answer on Stackoverflow
Solution 15 - SqlAbdullah YousufView Answer on Stackoverflow
Solution 16 - SqlKeithTheBipedView Answer on Stackoverflow