基于ID匹配从一个表到另一个表的SQL更新

885 sql sql-server select join sql-update

我有一个带account numbers和的数据库card numbers.我将这些文件与update任何卡号匹配到帐号,以便我只使用帐号.

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

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

LeadID  AccountNumber
147         5807811235
150         5807811326
185         7006100100007267039
Run Code Online (Sandbox Code Playgroud)

这是RetrieveAccountNumber表,我需要更新:

LeadID  AccountNumber
147         7006100100007266957
150         7006100100007267039
Run Code Online (Sandbox Code Playgroud)

我试过以下,但到目前为止没有运气:

UPDATE [Sales_Lead].[dbo].[Sales_Import] 
SET    [AccountNumber] = (SELECT RetrieveAccountNumber.AccountNumber 
                          FROM   RetrieveAccountNumber 
                          WHERE  [Sales_Lead].[dbo].[Sales_Import]. LeadID = 
                                                RetrieveAccountNumber.LeadID) 
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*sen 1311

我相信一个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;
Run Code Online (Sandbox Code Playgroud)

MySQL和MariaDB

UPDATE
    Sales_Import SI,
    RetrieveAccountNumber RAN
SET
    SI.AccountNumber = RAN.AccountNumber
WHERE
    SI.LeadID = RAN.LeadID;
Run Code Online (Sandbox Code Playgroud)

  • 这似乎对mssql很好,但似乎不适用于mysql.这似乎可以完成这项工作:`UPDATE Sales_Import,RetrieveAccountNumber SET Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber,其中Sales_Import.LeadID = RetrieveAccountNumber.LeadID;`.稍微偏离主题,但可能会有所帮助 (92认同)
  • 您可能希望在UPDATE子句中使用表别名,否则如果您在任何时候自己加入表,它将导致问题. (17认同)
  • 在set子句中,您应该将`SI.AccountNumber`更改为`AccountNumber`,否则它将失败. (14认同)
  • 我认为没有必要进行内部联接.下面的Vonki解决方案有效:UPDATE [Sales_Lead].[dbo].[Sales_Import] SET [AccountNumber] = RetrieveAccountNumber.AccountNumber FROM RetrieveAccountNumber WHERE [Sales_Lead].[dbo].[Sales_Import] .LeadID = RetrieveAccountNumber.LeadID (7认同)
  • MS-Access 使用不同的 UPDATE 和 JOIN 语句。看看:http://www.sql-und-xml.de/sql-tutorial/update-aktualisieren-der-zeilen.html (2认同)

Shi*_*ant 279

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

UPDATE table2 
SET table2.col1 = table1.col1, 
table2.col2 = table1.col2,
...
FROM table1, table2 
WHERE table1.memberid = table2.memberid
Run Code Online (Sandbox Code Playgroud)

您还可以添加条件以复制特定数据.

  • 这是有效的,但你不需要FROM UPDATE table2中的table2 SET table2.col1 = table1.col1,table2.col2 = table1.col2,... FROM table1 WHERE table1.memberid = table2.memberid (2认同)
  • 这没有用,但是UPDATE table2,table1 SET table2.col1 = table1.col1,... WHERE table1.memberid = table2.memberid(mysql和phpmyadmin) (2认同)

Mar*_*ith 155

对于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;
Run Code Online (Sandbox Code Playgroud)

不幸的是,选择哪种使用可能不会纯粹归结为优选的风格.执行MERGESQL Server中已患各种错误.Aaron Bertrand在这里编制了一份报告清单.

  • 抬头为'MERGE`. (10认同)
  • 使用 MERGE 的参数(包括 [来自 sqlblog.com 的帖子](http://sqlblog.com/blogs/hugo_kornelis/archive/2008/03/10/lets-deprecate-update-from.aspx)中的参数)上面链接) 可能很有说服力,但要考虑的一件事可能是 [根据 MSDN](https://msdn.microsoft.com/en-us/library/bb510625.aspx):_...MERGE 语句在以下情况下效果最佳两个表具有复杂的匹配特征混合...当简单地根据另一个表的行更新一个表时,可以使用基本的 INSERT、UPDATE 和 DELETE 语句来提高性能和可伸缩性_ (3认同)
  • 我从来不知道合并语法.它比Update + Join更清洁. (2认同)
  • @jkp1187 这个问题被标记为 SQL Server。所以回复:FWIW - 大约为零。 (2认同)

Tig*_*z32 90

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

SQL Server

UPDATE 
     t1
SET 
     t1.column = t2.column
FROM 
     Table1 t1 
     INNER JOIN Table2 t2 
     ON t1.id = t2.id;
Run Code Online (Sandbox Code Playgroud)

Oracle(和SQL Server)

UPDATE 
     t1
SET 
     t1.colmun = t2.column 
FROM 
     Table1 t1, 
     Table2 t2 
WHERE 
     t1.ID = t2.ID;
Run Code Online (Sandbox Code Playgroud)

MySQL的

UPDATE 
     Table1 t1, 
     Table2 t2
SET 
     t1.column = t2.column 
WHERE
     t1.ID = t2.ID;
Run Code Online (Sandbox Code Playgroud)

  • 请注意,至少对于 SQL Server,在顶部更新子句中使用别名而不是表名(`update t1...` 而不是 `update Table1...`) (4认同)
  • Oracle版本不起作用。正在获取ORA-00933 (2认同)
  • 在 Oracle 中不起作用:ORA-00933:SQL 命令未正确结束 (2认同)

Vin*_*vic 34

看来你正在使用MSSQL,如果我没记错的话,它是这样完成的:

UPDATE [Sales_Lead].[dbo].[Sales_Import] SET [AccountNumber] = 
RetrieveAccountNumber.AccountNumber 
FROM RetrieveAccountNumber 
WHERE [Sales_Lead].[dbo].[Sales_Import].LeadID = RetrieveAccountNumber.LeadID
Run Code Online (Sandbox Code Playgroud)


Kje*_*sen 33

foo.new设置nullfoo没有匹配键的行时,我遇到了同样的问题bar.我在Oracle中做了类似的事情:

update foo
set    foo.new = (select bar.new
                  from bar 
                  where foo.key = bar.key)
where exists (select 1
              from bar
              where foo.key = bar.key)

  • 因为foo中没有匹配的每一行最终都为null,因为select语句产生了null.希望这比我第一次尝试解释它更清楚. (6认同)
  • 为什么需要*WHERE EXISTS*? (4认同)

pet*_*ter 32

对于PostgreSQL:

UPDATE Sales_Import SI
SET AccountNumber = RAN.AccountNumber
FROM RetrieveAccountNumber RAN
WHERE RAN.LeadID = SI.LeadID; 
Run Code Online (Sandbox Code Playgroud)

  • 我犯的错误是:SET SI.AccountNumber = RAN.AccountNumber。不过,我想知道为什么在 postgresql 中它是错误的?谁能解释一下吗? (3认同)

小智 27

对于工作正常的MySql:

UPDATE
    Sales_Import SI,RetrieveAccountNumber RAN
SET
    SI.AccountNumber = RAN.AccountNumber
WHERE
    SI.LeadID = RAN.LeadID
Run Code Online (Sandbox Code Playgroud)


Abh*_*nyu 22

这是在SQL Server中对我有用的:

UPDATE [AspNetUsers] SET

[AspNetUsers].[OrganizationId] = [UserProfile].[OrganizationId],
[AspNetUsers].[Name] = [UserProfile].[Name]

FROM [AspNetUsers], [UserProfile]
WHERE [AspNetUsers].[Id] = [UserProfile].[Id];
Run Code Online (Sandbox Code Playgroud)


小智 17

谢谢你的回复.我发现了一个解决方案.

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)  
Run Code Online (Sandbox Code Playgroud)

  • 无论代码是否有效,您都应该看看发布的其他两个解决方案.它们更清晰,更不容易出错,而且几乎肯定更快. (16认同)
  • 关于此解决方案的一个注释,UPDATE ... FROM是专有的,因此,如果由于使用的是SQL 2005或更早版本而无法使用MERGE语句,则这是一种符合ANSI标准的方法,可以使用MSSQL中的表源执行更新.资料来源:http://sqlblog.com/blogs/hugo_kornelis/archive/2008/03/10/lets-deprecate-update-from.aspx (2认同)
  • 唯一对我有用的解决方案,因为它是标准的 SQL 更新语句(UPDATE SET WHERE),非常感谢 (2认同)

sam*_*adi 11

微软数据库

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';
Run Code Online (Sandbox Code Playgroud)

甲骨文 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  ;
Run Code Online (Sandbox Code Playgroud)


Gil*_*gio 8

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

UPDATE Sales_Import, RetrieveAccountNumber 
SET Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber 
where Sales_Import.LeadID = RetrieveAccountNumber.LeadID;
Run Code Online (Sandbox Code Playgroud)

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


小智 7

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

UPDATE table2, table1 SET table2.by_department = table1.department WHERE table1.id = table2.by_id
Run Code Online (Sandbox Code Playgroud)

注意:如果您根据您的 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
Run Code Online (Sandbox Code Playgroud)


小智 6

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

UPDATE table2 
SET table2.col1 = table1.col1, 
table2.col2 = table1.col2,
...
FROM table1, table2 
WHERE table1.memberid = table2.memberid
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我只能说在 SQL Server 2017 中这非常有效。就像为未来的人做笔记一样。没必要加入他们。 (3认同)

小智 6

id 匹配时从一张表更新到另一张表

UPDATE 
     TABLE1 t1, 
     TABLE2 t2
SET 
     t1.column_name = t2.column_name 
WHERE
     t1.id = t2.id;
Run Code Online (Sandbox Code Playgroud)

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

Ula*_*mir 6

总结其他答案,仅当“匹配存在”时,如何使用另一个表中的数据更新目标表有 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)
Run Code Online (Sandbox Code Playgroud)

内部联接:

update si
set si.AccountNumber = ran.AccountNumber
from Sales_Import si inner join RetrieveAccountNumber ran on si.LeadID = ran.LeadID
Run Code Online (Sandbox Code Playgroud)

交叉连接:

update si
set si.AccountNumber = ran.AccountNumber
from Sales_Import si, RetrieveAccountNumber ran
where si.LeadID = ran.LeadID
Run Code Online (Sandbox Code Playgroud)

合并:

merge into Sales_Import si
using RetrieveAccountNumber ran on si.LeadID = ran.LeadID 
when matched then update set si.accountnumber = ran.accountnumber;
Run Code Online (Sandbox Code Playgroud)

所有变体都更加简单且易于理解,我个人更喜欢“内部连接”选项。但它们中的任何一个都可以使用,开发人员必须根据他/她的需求选择“更好的选项”

从性能角度来看,带有 join-s 的变体更可取: 在此输入图像描述


jak*_*tus 5

它与 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
);
Run Code Online (Sandbox Code Playgroud)


小智 5

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

update database1..Ciudad
set CiudadDistrito=c2.CiudadDistrito

FROM database1..Ciudad c1
 inner join 
  database2..Ciudad c2 on c2.CiudadID=c1.CiudadID
Run Code Online (Sandbox Code Playgroud)