sql - with - update table from another table postgres
SQL update from one Table to another based on a ID match (13)
I have a database with
account numbers and
card numbers. I match these to a file to
update any card numbers to the account number, so that I am only working with account numbers.
I created a view linking the table to the account/card database to return the
Table ID and the related account number, and now I need to update those records where the ID matches with the Account Number.
This is the
Sales_Import table, where the
account number field needs to be updated:
LeadID AccountNumber 147 5807811235 150 5807811326 185 7006100100007267039
And this is the
RetrieveAccountNumber table, where I need to update from:
LeadID AccountNumber 147 7006100100007266957 150 7006100100007267039
I tried the below, but no luck so far:
UPDATE [Sales_Lead].[dbo].[Sales_Import] SET [AccountNumber] = (SELECT RetrieveAccountNumber.AccountNumber FROM RetrieveAccountNumber WHERE [Sales_Lead].[dbo].[Sales_Import]. LeadID = RetrieveAccountNumber.LeadID)
It updates the card numbers to account numbers, but the account numbers gets replaced by
try this :
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
For MySql that works fine:
UPDATE Sales_Import SI,RetrieveAccountNumber RAN SET SI.AccountNumber = RAN.AccountNumber WHERE SI.LeadID = RAN.LeadID
For SQL Server 2008 + Using
MERGE rather than the proprietary
UPDATE ... FROM syntax has some appeal.
As well as being standard SQL and thus more portable it also will raise an error in the event of there being multiple joined rows on the source side (and thus multiple possible different values to use in the update) rather than having the final result be undeterministic.
MERGE INTO Sales_Import USING RetrieveAccountNumber ON Sales_Import.LeadID = RetrieveAccountNumber.LeadID WHEN MATCHED THEN UPDATE SET AccountNumber = RetrieveAccountNumber.AccountNumber;
Unfortunately the choice of which to use may not come down purely to preferred style however. The implementation of
MERGE in SQL Server has been afflicted with various bugs. Aaron Bertrand has compiled a list of the reported ones here.
Generic answer for future developers.
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;
UPDATE Table1 t1, Table2 t2 SET t1.column = t2.column WHERE t1.ID = t2.ID;
I believe an
UPDATE FROM with a
JOIN will help:
UPDATE Sales_Import SET Sales_Import.AccountNumber = RAN.AccountNumber FROM Sales_Import SI INNER JOIN RetrieveAccountNumber RAN ON SI.LeadID = RAN.LeadID;
MySQL and MariaDB
UPDATE Sales_Import SI, RetrieveAccountNumber RAN SET SI.AccountNumber = RAN.AccountNumber WHERE SI.LeadID = RAN.LeadID;
I had the same problem with
foo.new being set to
null for rows of
foo that had no matching key in
bar. I did something like this in 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)
I'd like to add one extra thing.
Don't update a value with the same value, it generates extra logging and unnecessary overhead. See example below - it will only perform the update on 2 records despite linking on 3.
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
If above answers not working for you try this
Update Sales_Import A left join RetrieveAccountNumber B on A.LeadID = B.LeadID Set A.AccountNumber = B.AccountNumber where A.LeadID = B.LeadID
Thanks for the responses. I found a solution tho.
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)
The below SQL someone suggested, does NOT work in SQL Server. This syntax reminds me of my old school class:
UPDATE table2 SET table2.col1 = table1.col1, table2.col2 = table1.col2, ... FROM table1, table2 WHERE table1.memberid = table2.memberid
All other queries using
NOT IN or
NOT EXISTS are not recommended. NULLs show up because OP compares entire dataset with smaller subset, then of course there will be matching problem. This must be fixed by writing proper SQL with correct
JOIN instead of dodging problem by using
NOT IN. You might run into other problems by using
NOT IN or
NOT EXISTS in this case.
My vote for the top one, which is conventional way of updating a table based on another table by joining in SQL Server. Like I said, you cannot use two tables in same
UPDATE statement in SQL Server unless you join them first.
This will allow you to update a table based on the column value not being found in another table.
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 )
This will update a table based on the column value being found in both tables.
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 )
Use the following block of query to update Table1 with Table2 based on ID:
UPDATE Sales_Import, RetrieveAccountNumber SET Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber where Sales_Import.LeadID = RetrieveAccountNumber.LeadID;
This is the easiest way to tackle this problem.
update within the same table:
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