2025年3月3日 星期一

【SQL Server】用其它的 Table 來更新資料(Update From Table)

當更新資料,需要從多個Table取值時,除了使用UPDATE TABLE,MERGE INTO其實也頗好用的,可以把INSERT跟UPDATE都寫在一起,讓語法更簡潔,不過,要注意的是MATCHED跟NOT MATCHED在語法中只能出現一次,所以,如果有多重更新情境的時候,就沒那麼合適了!




對開發人員的通用解法


SQL Server


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

Oracle (and 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;



從多個Table取值的解法


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';

Oracle 11g

(MS SQL也適用這語法,USING的部份亦可視需要,事先生成暫存Table(@Table或#Table),再套用在語法中)

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;


總結其他答案

只有當「匹配存在」時,才有 4 種方法可以使用另一個表中的資料來更新目標表

Query and sub-query


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
)

INNER JOIN


UPDATE si
SET 
si.AccountNumber = ran.AccountNumber
FROM 
Sales_Import si 
INNER JOIN RetrieveAccountNumber ran 
on si.LeadID = ran.LeadID

Cross JOIN


UPDATE si
SET 
si.AccountNumber = ran.AccountNumber
FROM 
Sales_Import si, 
RetrieveAccountNumber ran
WHERE 
si.LeadID = ran.LeadID

Merge


MERGE INTO Sales_Import si
USING 
RetrieveAccountNumber ran 
on si.LeadID = ran.LeadID
WHEN MATCHED THEN 
UPDATE SET 
si.accountnumber = ran.accountnumber;

從性能角度來看,帶有 JOIN-s 的變體更可取:










參考文件:

沒有留言:

張貼留言