我有一个有帐号和卡号的数据库。我将这些匹配到一个文件,以将任何卡号更新为帐号,这样我只使用帐号。

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

这是Sales_Import表,其中的帐号字段需要更新:

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 Server

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;

其他回答

总结其他答案,关于如何仅在“匹配存在”时使用来自另一个表的数据更新目标表,有4种变体

查询和子查询:

update si
set    si.AccountNumber = (
    select ran.AccountNumber 
    from   RetrieveAccountNumber ran
    where  si.LeadID = ran.LeadID
)
from Sales_Import si
where exists (select * from RetrieveAccountNumber ran where ran.LeadID = si.LeadID)

内连接:

update si
set si.AccountNumber = ran.AccountNumber
from Sales_Import si inner join RetrieveAccountNumber ran on si.LeadID = ran.LeadID

交叉连接:

update si
set si.AccountNumber = ran.AccountNumber
from Sales_Import si, RetrieveAccountNumber ran
where si.LeadID = ran.LeadID

走:

merge into Sales_Import si
using RetrieveAccountNumber ran on si.LeadID = ran.LeadID 
when matched then update set si.accountnumber = ran.accountnumber;

所有的变体都是更少的琐碎和可以理解的,我个人更喜欢“内部连接”选项。但其中任何一种都可以使用,开发者必须根据自己的需求选择“更好的选项”

从性能的角度来看,使用join的变体更可取:

我相信一个带JOIN的UPDATE FROM会有帮助:

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;

它与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
);

对于SQL Server 2008 +使用MERGE而不是专有的更新…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在这里整理了一份报告的清单。

我认为这是一个简单的例子,可能有人会更容易理解,

        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