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

前端 未结 16 1266
名媛妹妹
名媛妹妹 2020-11-21 11:51

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

Table: sale

id (int)
udid         


        
相关标签:
16条回答
  • 2020-11-21 12:12

    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 
    
    0 讨论(0)
  • 2020-11-21 12:12

    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

    0 讨论(0)
  • 2020-11-21 12:12

    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');
    
    0 讨论(0)
  • 2020-11-21 12:14
    UPDATE tblAppraisalBasicData
    SET tblAppraisalBasicData.ISCbo=1
    FROM tblAppraisalBasicData SI INNER JOIN  aaa_test RAN ON SI.EmpID = RAN.ID
    
    0 讨论(0)
  • 2020-11-21 12:15

    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
     );
    
    0 讨论(0)
  • 2020-11-21 12:15

    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
    
    0 讨论(0)
提交回复
热议问题