【问题标题】:SQL update from one Table to another based on a ID matchSQL 根据 ID 匹配从一个表更新到另一个表
【发布时间】:2010-09-18 11:49:01
【问题描述】:

我有一个包含account numberscard numbers 的数据库。我将这些与update 的文件匹配到任何卡号到帐号,因此我只使用帐号。

我创建了一个将表链接到帐户/卡数据库的视图以返回 Table ID 和相关的帐号,现在我需要更新 ID 与帐号匹配的那些记录。

这是Sales_Import 表,其中account number 字段需要更新:

LeadID  AccountNumber
147         5807811235
150         5807811326
185         7006100100007267039

这是RetrieveAccountNumber 表,我需要从中更新:

LeadID  AccountNumber
147         7006100100007266957
150         7006100100007267039

我尝试了以下方法,但到目前为止没有运气:

UPDATE [Sales_Lead].[dbo].[Sales_Import] 
SET    [AccountNumber] = (SELECT RetrieveAccountNumber.AccountNumber 
                          FROM   RetrieveAccountNumber 
                          WHERE  [Sales_Lead].[dbo].[Sales_Import]. LeadID = 
                                                RetrieveAccountNumber.LeadID) 

它将卡号更新为帐号,但帐号被替换为NULL

【问题讨论】:

    标签: sql sql-server select join sql-update


    【解决方案1】:

    我相信UPDATE FROMJOIN 会有所帮助:

    MS SQL

    UPDATE
        Sales_Import
    SET
        Sales_Import.AccountNumber = RAN.AccountNumber
    FROM
        Sales_Import SI
    INNER JOIN
        RetrieveAccountNumber RAN
    ON 
        SI.LeadID = RAN.LeadID;
    

    MySQL 和 MariaDB

    UPDATE
        Sales_Import SI,
        RetrieveAccountNumber RAN
    SET
        SI.AccountNumber = RAN.AccountNumber
    WHERE
        SI.LeadID = RAN.LeadID;
    

    【讨论】:

    • 您可能希望在 UPDATE 子句中使用表别名,否则如果您在任何时候自加入表都会导致问题。
    • 在set子句中你应该把SI.AccountNumber改成AccountNumber否则会失败。
    • MS-Access 使用不同的 UPDATE 和 JOIN 语句。看看:sql-und-xml.de/sql-tutorial/…
    • 这对 mssql 似乎没问题,但在 mysql 中似乎不起作用。不过,这似乎可以完成工作:UPDATE Sales_Import, RetrieveAccountNumber SET Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber where Sales_Import.LeadID = RetrieveAccountNumber.LeadID;。稍微偏离主题,但可能会有所帮助
    • 我认为不需要内连接。下面的 Vonki 解决方案有效: UPDATE [Sales_Lead].[dbo].[Sales_Import] SET [AccountNumber] = RetrieveAccountNumber.AccountNumber FROM RetrieveAccountNumber WHERE [Sales_Lead].[dbo].[Sales_Import].LeadID = RetrieveAccountNumber.LeadID
    【解决方案2】:

    好像你用的是MSSQL,那么,如果我没记错的话,是这样完成的:

    UPDATE [Sales_Lead].[dbo].[Sales_Import] SET [AccountNumber] = 
    RetrieveAccountNumber.AccountNumber 
    FROM RetrieveAccountNumber 
    WHERE [Sales_Lead].[dbo].[Sales_Import].LeadID = RetrieveAccountNumber.LeadID
    

    【讨论】:

      【解决方案3】:

      感谢您的回复。我找到了解决办法。

      UPDATE Sales_Import 
      SET    AccountNumber = (SELECT RetrieveAccountNumber.AccountNumber 
                                FROM   RetrieveAccountNumber 
                                WHERE  Sales_Import.leadid =RetrieveAccountNumber.LeadID) 
      WHERE Sales_Import.leadid = (SELECT  RetrieveAccountNumber.LeadID 
                                   FROM   RetrieveAccountNumber 
                                   WHERE  Sales_Import.leadid = RetrieveAccountNumber.LeadID)  
      

      【讨论】:

      • 此处的代码是否有效,您可能应该查看发布的其他两个解决方案。它们更清晰,更不容易出错,而且几乎可以肯定更快。
      • 请注意此解决方案,UPDATE...FROM 是专有的,因此,如果您因为使用 SQL 2005 或更早版本而无法使用 MERGE 语句,则这是一种符合 ANSI 的执行更新方法使用 MSSQL 中的表源。来源:sqlblog.com/blogs/hugo_kornelis/archive/2008/03/10/…
      • 唯一适合我的解决方案,因为它是标准 SQL 更新语句 (UPDATE SET WHERE),非常感谢
      【解决方案4】:

      对于foo 的行,foo.new 设置为null,而bar 中没有匹配的键,我遇到了同样的问题。我在 Oracle 中做了这样的事情:

      更新 foo 设置 foo.new = (选择 bar.new 从酒吧 其中 foo.key = bar.key) 在哪里存在(选择 1 从酒吧 其中 foo.key = bar.key)

      【讨论】:

      • 为什么需要WHERE EXISTS
      • 因为 foo 中的每一行在 bar 中没有匹配项最终都为 null,因为 select 语句产生了 null。希望这比我第一次解释它时更清楚。
      • stackoverflow.com/questions/224732/…下方查看这个答案
      • @KjellAndreassen 你已经解决了我的问题。感谢您的代码。
      【解决方案5】:

      将内容从一个表复制到另一个表的简单方法如下:

      UPDATE table2 
      SET table2.col1 = table1.col1, 
      table2.col2 = table1.col2,
      ...
      FROM table1, table2 
      WHERE table1.memberid = table2.memberid
      

      您还可以添加条件以获取复制的特定数据。

      【讨论】:

      • 这行得通,但你不需要 FROM UPDATE table2 中的 table2 SET table2.col1 = table1.col1, table2.col2 = table1.col2, ... FROM table1 WHERE table1.memberid = table2.memberid
      • 这没用,但是 UPDATE table2, table1 SET table2.col1 = table1.col1, ... WHERE table1.memberid = table2.memberid (mysql and phpmyadmin)
      【解决方案6】:

      对于 SQL Server 2008 + 使用 MERGE 而不是专有的 UPDATE ... FROM 语法有一些吸引力。

      除了是标准 SQL,因此更便携,如果源端有多个连接行(因此在更新中使用多个可能的不同值)而不是最终结果,它也会引发错误结果是不确定的。

      MERGE INTO Sales_Import
         USING RetrieveAccountNumber
            ON Sales_Import.LeadID = RetrieveAccountNumber.LeadID
      WHEN MATCHED THEN
         UPDATE 
            SET AccountNumber = RetrieveAccountNumber.AccountNumber;
      

      不幸的是,选择使用哪种风格可能并不完全取决于首选风格。 SQL Server 中MERGE 的实现存在各种错误。 Aaron Bertrand 整理了一份the reported ones here 的列表。

      【讨论】:

      • 我从来不知道合并语法。它比 Update + Join 干净得多。
      • +1 用于报告 MERGE SQL Server 的实施
      • 非常感谢马丁!我一直在搜索这个,因为很多天终于让它工作了:)
      • 使用 MERGE 的参数(包括上面链接的 the post from sqlblog.com 中的参数)可能很有吸引力,但要考虑的一件事可能是 according to MSDN: ...MERGE 语句在以下情况下效果最好这两个表具有复杂的匹配特征...当根据另一个表的行简单地更新一个表时,可以使用基本的 INSERT、UPDATE 和 DELETE 语句来提高性能和可伸缩性
      • @jkp1187 这个问题被标记为 SQL Server。所以回复:FWIW - 大约为零。
      【解决方案7】:

      对于运行良好的 MySql:

      UPDATE
          Sales_Import SI,RetrieveAccountNumber RAN
      SET
          SI.AccountNumber = RAN.AccountNumber
      WHERE
          SI.LeadID = RAN.LeadID
      

      【讨论】:

        【解决方案8】:

        我认为这是一个简单的例子,也许有人会更容易,

                DECLARE @TB1 TABLE
                (
                    No Int
                    ,Name NVarchar(50)
                )
        
                DECLARE @TB2 TABLE
                (
                    No Int
                    ,Name NVarchar(50)
                )
        
                INSERT INTO @TB1 VALUES(1,'asdf');
                INSERT INTO @TB1 VALUES(2,'awerq');
        
        
                INSERT INTO @TB2 VALUES(1,';oiup');
                INSERT INTO @TB2 VALUES(2,'lkjhj');
        
                SELECT * FROM @TB1
        
                UPDATE @TB1 SET Name =S.Name
                FROM @TB1 T
                INNER JOIN @TB2 S
                        ON S.No = T.No
        
                SELECT * FROM @TB1
        

        【讨论】:

          【解决方案9】:

          在同一张表内更新:

            DECLARE @TB1 TABLE
              (
                  No Int
                  ,Name NVarchar(50)
                  ,linkNo int
              )
          
              DECLARE @TB2 TABLE
              (
                  No Int
                  ,Name NVarchar(50)
                  ,linkNo int
              )
          
              INSERT INTO @TB1 VALUES(1,'changed person data',  0);
              INSERT INTO @TB1 VALUES(2,'old linked data of person', 1);
          
          INSERT INTO @TB2 SELECT * FROM @TB1 WHERE linkNo = 0
          
          
          SELECT * FROM @TB1
          SELECT * FROM @TB2
          
          
              UPDATE @TB1 
                  SET Name = T2.Name
              FROM        @TB1 T1
              INNER JOIN  @TB2 T2 ON T2.No = T1.linkNo
          
              SELECT * FROM @TB1
          

          【讨论】:

            【解决方案10】:

            对于 PostgreSQL:

            UPDATE Sales_Import SI
            SET AccountNumber = RAN.AccountNumber
            FROM RetrieveAccountNumber RAN
            WHERE RAN.LeadID = SI.LeadID; 
            

            【讨论】:

            • 我做的错误是:SET SI.AccountNumber = RAN.AccountNumber。不过,我想知道为什么它在 postgresql 中是错误的?谁能解释一下?
            • 伙计,你今天救了我的命。非常感谢:)
            【解决方案11】:

            这将允许您根据在另一个表中找不到的列值来更新表。

                UPDATE table1 SET table1.column = 'some_new_val' WHERE table1.id IN (
                        SELECT * 
                        FROM (
                                SELECT table1.id
                                FROM  table1 
                                LEFT JOIN table2 ON ( table2.column = table1.column ) 
                                WHERE table1.column = 'some_expected_val'
                                AND table12.column IS NULL
                        ) AS Xalias
                )
            

            这将根据在两个表中找到的列值更新表。

                UPDATE table1 SET table1.column = 'some_new_val' WHERE table1.id IN (
                        SELECT * 
                        FROM (
                                SELECT table1.id
                                FROM  table1 
                                JOIN table2 ON ( table2.column = table1.column ) 
                                WHERE table1.column = 'some_expected_val'
                        ) AS Xalias
                )
            

            【讨论】:

              【解决方案12】:

              它适用于 postgresql

              UPDATE application
              SET omts_received_date = (
                  SELECT
                      date_created
                  FROM
                      application_history
                  WHERE
                      application.id = application_history.application_id
                  AND application_history.application_status_id = 8
              );
              

              【讨论】:

                【解决方案13】:

                下面有人建议的 SQL 在 SQL Server 中不起作用。这种语法让我想起了我的老学校:

                UPDATE table2 
                SET table2.col1 = table1.col1, 
                table2.col2 = table1.col2,
                ...
                FROM table1, table2 
                WHERE table1.memberid = table2.memberid
                

                不推荐使用NOT INNOT EXISTS 的所有其他查询。出现 NULL 是因为 OP 将整个数据集与较小的子集进行比较,那么当然会有匹配问题。这必须通过使用正确的JOIN 编写正确的 SQL 来解决,而不是使用NOT IN 来回避问题。在这种情况下使用NOT INNOT EXISTS 可能会遇到其他问题。

                我投票给了第一名,这是通过加入 SQL Server 来更新基于另一个表的表的传统方式。就像我说的,你不能在 SQL Server 中的同一 UPDATE 语句中使用两个表,除非你先加入它们。

                【讨论】:

                • 我只能说,在 SQL Server 2017 中它运行得非常好。就像给未来的人的便条一样。无需加入他们。
                【解决方案14】:

                未来开发人员的通用答案。

                SQL 服务器

                UPDATE 
                     t1
                SET 
                     t1.column = t2.column
                FROM 
                     Table1 t1 
                     INNER JOIN Table2 t2 
                     ON t1.id = t2.id;
                

                Oracle(和 SQL Server)

                UPDATE 
                     t1
                SET 
                     t1.colmun = t2.column 
                FROM 
                     Table1 t1, 
                     Table2 t2 
                WHERE 
                     t1.ID = t2.ID;
                

                MySQL

                UPDATE 
                     Table1 t1, 
                     Table2 t2
                SET 
                     t1.column = t2.column 
                WHERE
                     t1.ID = t2.ID;
                

                【讨论】:

                • 请注意,至少对于 SQL Server,在顶部更新子句中使用别名而不是表名(update t1... 而不是 update Table1...
                • 在 Oracle 中不起作用:ORA-00933:SQL 命令未正确结束
                • ORA-00933 的建议解决方案是什么?
                • oracle 变体对我不起作用
                【解决方案15】:

                试试这个:

                UPDATE
                    Table_A
                SET
                    Table_A.AccountNumber = Table_B.AccountNumber ,
                FROM
                    dbo.Sales_Import AS Table_A
                    INNER JOIN dbo.RetrieveAccountNumber AS Table_B
                        ON Table_A.LeadID = Table_B.LeadID 
                WHERE
                    Table_A.LeadID = Table_B.LeadID
                

                【讨论】:

                  【解决方案16】:

                  我想补充一点。

                  不要用相同的值更新值,它会产生额外的日志记录和不必要的开销。 请参见下面的示例 - 尽管链接在 3 上,但它只会对 2 条记录执行更新。

                  DROP TABLE #TMP1
                  DROP TABLE #TMP2
                  CREATE TABLE #TMP1(LeadID Int,AccountNumber NVarchar(50))
                  CREATE TABLE #TMP2(LeadID Int,AccountNumber NVarchar(50))
                  
                  INSERT INTO #TMP1 VALUES
                  (147,'5807811235')
                  ,(150,'5807811326')
                  ,(185,'7006100100007267039');
                  
                  INSERT INTO #TMP2 VALUES
                  (147,'7006100100007266957')
                  ,(150,'7006100100007267039')
                  ,(185,'7006100100007267039');
                  
                  UPDATE A
                  SET A.AccountNumber = B.AccountNumber
                  FROM
                      #TMP1 A 
                          INNER JOIN #TMP2 B
                          ON
                          A.LeadID = B.LeadID
                  WHERE
                      A.AccountNumber <> B.AccountNumber  --DON'T OVERWRITE A VALUE WITH THE SAME VALUE
                  
                  SELECT * FROM #TMP1
                  

                  【讨论】:

                    【解决方案17】:

                    使用以下查询块根据 ID 将 Table1 更新为 Table2:

                    UPDATE Sales_Import, RetrieveAccountNumber 
                    SET Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber 
                    where Sales_Import.LeadID = RetrieveAccountNumber.LeadID;
                    

                    这是解决这个问题的最简单的方法

                    【讨论】:

                      【解决方案18】:

                      如果上面的答案不适合你试试这个

                      Update Sales_Import A left join RetrieveAccountNumber B on A.LeadID = B.LeadID
                      Set A.AccountNumber = B.AccountNumber
                      where A.LeadID = B.LeadID 
                      

                      【讨论】:

                        【解决方案19】:

                        以下是在 SQL Server 中对我有用的方法:

                        UPDATE [AspNetUsers] SET
                        
                        [AspNetUsers].[OrganizationId] = [UserProfile].[OrganizationId],
                        [AspNetUsers].[Name] = [UserProfile].[Name]
                        
                        FROM [AspNetUsers], [UserProfile]
                        WHERE [AspNetUsers].[Id] = [UserProfile].[Id];
                        

                        【讨论】:

                          【解决方案20】:

                          甲骨文 11g

                          merge into Sales_Import
                          using RetrieveAccountNumber
                          on (Sales_Import.LeadId = RetrieveAccountNumber.LeadId)
                          when matched then update set Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber;
                          

                          【讨论】:

                            【解决方案21】:

                            MS Sql

                            UPDATE  c4 SET Price=cp.Price*p.FactorRate FROM TableNamea_A c4
                            inner join TableNamea_B p on c4.Calcid=p.calcid 
                            inner join TableNamea_A cp on c4.Calcid=cp.calcid 
                            WHERE c4..Name='MyName';
                            

                            甲骨文 11g

                                    MERGE INTO  TableNamea_A u 
                                    using
                                    (
                                            SELECT c4.TableName_A_ID,(cp.Price*p.FactorRate) as CalcTot 
                                            FROM TableNamea_A c4
                                            inner join TableNamea_B p on c4.Calcid=p.calcid 
                                            inner join TableNamea_A cp on c4.Calcid=cp.calcid 
                                            WHERE p.Name='MyName' 
                                    )  rt
                                    on (u.TableNamea_A_ID=rt.TableNamea_B_ID)
                                    WHEN MATCHED THEN
                                    Update set Price=CalcTot  ;
                            

                            【讨论】:

                              【解决方案22】:

                              如果表位于不同的数据库中。 (MSSQL)

                              update database1..Ciudad
                              set CiudadDistrito=c2.CiudadDistrito
                              
                              FROM database1..Ciudad c1
                               inner join 
                                database2..Ciudad c2 on c2.CiudadID=c1.CiudadID
                              

                              【讨论】:

                                【解决方案23】:

                                在 id 匹配时从一个表更新到另一个表

                                UPDATE 
                                     TABLE1 t1, 
                                     TABLE2 t2
                                SET 
                                     t1.column_name = t2.column_name 
                                WHERE
                                     t1.id = t2.id;
                                

                                【讨论】:

                                • 在 SQL Server v18 中,似乎不允许在 UPDATE 中使用第二个表。它抱怨逗号并想要一个 SET 语句。也许这个解决方案适用于不同的数据库。
                                【解决方案24】:

                                MYSQL(这是我根据主键 id 等效恢复 all 特定列 reasonId 值的首选方式)

                                UPDATE `site` AS destination  
                                INNER JOIN `site_copy` AS backupOnTuesday 
                                      ON backupOnTuesday.`id` = destination.`id`
                                SET destdestination.`reasonId` = backupOnTuesday.`reasonId`
                                

                                【讨论】:

                                  【解决方案25】:

                                  这是 Mysql 和 Maria DB 所见过的最简单和最好的

                                  UPDATE table2, table1 SET table2.by_department = table1.department WHERE table1.id = table2.by_id
                                  

                                  注意:如果您遇到以下基于您的 Mysql/Maria DB 版本的错误“错误代码:1175。您正在使用安全更新模式,并且您尝试更新没有使用 KEY 列的 WHERE 的表来禁用安全模式, 切换偏好中的选项”

                                  然后像这样运行代码

                                  SET SQL_SAFE_UPDATES=0;
                                  UPDATE table2, table1 SET table2.by_department = table1.department WHERE table1.id = table2.by_id
                                  

                                  【讨论】:

                                    【解决方案26】:

                                    甲骨文

                                    使用

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

                                    【讨论】:

                                      【解决方案27】:

                                      对于 Oracle SQL,请尝试使用别名

                                      UPDATE Sales_Lead.dbo.Sales_Import SI 
                                      SET SI.AccountNumber = (SELECT RAN.AccountNumber FROM RetrieveAccountNumber RAN WHERE RAN.LeadID = SI.LeadID);
                                      

                                      【讨论】:

                                      • 你的回答似乎和很多人一样
                                      猜你喜欢
                                      • 2017-03-15
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 2015-02-01
                                      • 1970-01-01
                                      • 2013-01-20
                                      相关资源
                                      最近更新 更多