SQL Join and Update query - sql

So I want to update the action column to the value 'Insert' inside Table1, if the ids from Table1 and Table2 match but the UIDs dont.
Right now my query looks like
UPDATE Table1
SET Action = 'Insert'
FROM Table1
JOIN Table2 ON Table1.id = Table2.id
AND Table1.UID <> Table2.UID
This is setting the action to Insert even if the UIDs don't differ, can someone help me and explain why this is behaving this way?

My assumption is you have something like this:
Table1
id | UID | action
1 | 1 | bla
1 | 2 | bleck
1 | 3 | floop
Table2
id | UID | action
1 | 1 | bla
1 | 2 | bleck
1 | 4 | floop
And you hope to update the third row in Table1 because the UID isn't in Table2.
The problem is that the third row in Table2 matches all rows in Table1 on your condition: Table1.id = Table2.id AND Table1.UID <> Table2.UID
Which means that in this case, all rows in Table1 will be updated with Action = 'Insert'
I think you want to use NOT EXISTS():
UPDATE T1
SET Action = 'Insert'
FROM Table1 T1
WHERE NOT EXISTS (SELECT *
FROM Table2 T2
WHERE T1.id = T2.id
AND T1.UID = T2.UID)
Edit, more explanation on why the join fails:
This is a many to many join, meaning that the condition allows multiple rows from Table1 to match multiple rows from Table2
The easiest way to see this in action is to change your update to a select:
SELECT *
FROM Table1 T1
JOIN Table2 T2 on T1.id = T2.id
and T1.UID <> T2.UID
You may expect this to result in:
id | UID | action id | UID | action
1 | 3 | floop 1 | 4 | floop
But really it will result in:
id | UID | action id | UID | action
1 | 1 | bla 1 | 4 | floop
1 | 2 | bleck 1 | 4 | floop
1 | 3 | floop 1 | 4 | floop
This means that when you update you are hitting all the rows for id = 1 in Table1

If you put condition Table1.UID <> Table2.UID into WHERE clause, doesn't it solve your problem?
UPDATE Table1
SET Action = 'Insert'
FROM Table1
JOIN Table2 ON Table1.id = Table2.id
WHERE Table1.UID <> Table2.UID

Related

Update a table based on a condition

I have a column Table1.Tradedate and another column Table2.SettlementDate.
Based on the comparison between these 2, I want to update a column in table 2
IF (Table1.TradeDate <= Table2.SettlementDate)
BEGIN
UPDATE Table2 SET Status='Y'
END
This is what I have tried but I know its wrong, since the table will obviously contain more than 1 records. So, I believe what I should do is
use a join on 2 tables based on some #id to pick a particular record
check the IF condition for that particular record
update the Status column in table2.
I hope my approach is correct but I am writing it incorrectly.
Table1:
SKacc | Name | TradeDate | Othercolumns....
1 | xxx | 01/07/2019 |
2 | xxx | 01/06/2019 |
Table2:
SKAcc | Name | SettlementDate | Status |Other Columns....
1 | xxx | 01/08/2019 | NULL |
2 | xxx | 01/08/2019 | NULL |
Try below
update t2 set Status = 'Y'
from table2 t2
join table1 t1 on t1.id = t2.id
where t1.tradeDate <= t2.settlementDate
Try joining the two tables with the related column and then update the table you want to update with the value. Using inner join in the example but can change depending on the usecase
UPDATE Table2
SET Status = 'Y'
FROM Table2
INNER JOIN Table1 ON Table1.id = Table2.table1_id
WHERE Table1.TradeDate <= Table2.SettlementDate
I would not recommend a JOIN for this purpose. Instead:
update table2
set Status = 'Y'
where exists (select 1
from table1 t1
where t1.id = t2.id and
t1.tradeDate <= t2.settlementDate
);
The reason I recommend this version is because you have not specified that id is unique in table1. In general, you only want to use JOIN in UPDATE when you can guarantee that there is only one matching row.

What is the correct way from performance perspective to match(replace) every value in every row in temp table using SQL Server 2016 or 2017?

I am wondering what should I use in SQL Server 2016 or 2017 (CTE, LOOP, JOINS, CURSOR, REPLACE, etc) to match (replace) every value in every row in temp table? What is the best solution from performance perspective?
Source Table
|id |id2|
| 1 | 2 |
| 2 | 1 |
| 1 | 1 |
| 2 | 2 |
Mapping Table
|id |newid|
| 1 | 3 |
| 2 | 4 |
Expected result
|id |id2|
| 3 | 4 |
| 4 | 3 |
| 3 | 3 |
| 4 | 4 |
You may join the second table to the first table twice:
WITH cte AS (
SELECT
t1.id AS id_old,
t1.id2 AS id2_old,
t2a.newid AS id_new,
t2b.newid AS id2_new
FROM table1 t1
LEFT JOIN table2 t2a
ON t1.id = t2a.id
LEFT JOIN table2 t2b
ON t1.id2 = t2b.id
)
UPDATE cte
SET
id_old = id_new,
id2_old = id2_new;
Demo
Not sure if you want just a select here, or maybe an update, or an insert into another table. In any case, the core logic I gave above should work for all these cases.
You'd need to apply joins on update query. Something like this:
Update tblA set column1 = 'something', column2 = 'something'
from actualName tblA
inner join MappingTable tblB
on tblA.ID = tblB.ID
this query will compare eachrow with ids and if matched then it will update/replace the value of the column as you desire. :)
Do the self join only
SELECT t1.id2 as id, t2.id2
FROM table1 t
INNER JOIN table2 t1 on t1.id = t.id
INNER JOIN table2 t2 on t2.id = t.id2
This may have best performance from solutions posted here if you have indexes set appropriately:
select (select [newid] from MappingTable where id = [ST].[id]) [id],
(select [newid] from MappingTable where id = [ST].[id2]) [id2]
from SourecTable [ST]

I want to assign the name of table1 in table 2 thanks

UPDATE table1, (select top 1 [ID],chef,formateur,techni from table1 order by Num desc)
AS x SET table2.ID = x.[ID], table2.Nom = x.[chef], table2.Nom = x.[formateur],
table2.Nom = x.[techni]
WHERE table2.mission="chef" and table2.mission="Formateur" and table2.mission="techni" ;
returns
table2 table 1
ID | mission |Nom| ID |chef|Formateur|techni|
-------------------------------- ----------------------------
1 | chef | | 1 |nom1| nom2 | nom3|
2 | Formateur | | **Result**
3 | techni | | ID | mission | Nom|
--------------------------
1 | chef | nom1|
2 | Formateur| nom2|
3 | techni | nom3|
I want to assign the name of table1 in table 2.
Please i need your help :)
Data structure does not make sense. Table2 has only 3 records?
Your attempted example is updating Table1 when it appears you really want to update Table2. Why do you want to pull from just last record of Table1?
But try:
UPDATE Table2,
(SELECT TOP 1 Table1.ID, Table1.chef, Table1.formateur, Table1.techni
FROM Table1 ORDER BY Table1.ID DESC) AS Q
SET Table2.nom = Switch([mission]="chef",[chef],[mission]="formateur",[formateur],[mission]="techni",[techni]);

update foreign key from key in another table

I need a query that will take the primary key from one table (table 2) and place it in a second table (table 1) as a foreign key. The database is Microsoft Access 2007. I tried the following query but it did not work:
update table1
set table1.table2ID = table2.ID
FROM table1 INNER JOIN table2 on table1.name = table2.name
The two tables are as follows:
Table 1:
ID | table2ID | Name
--------------------------
1 | | Name1
2 | | Name2
3 | | Name1
Table 2:
ID | Name
-----------------
1 | Name1
2 | Name2
I want the result to be:
Table 1:
ID | table2ID | Name
--------------------------
1 | 1 | Name1
2 | 2 | Name2
3 | 1 | Name1
Try this:
update table1
INNER JOIN table2 ON table1.name = table2.name
SET table1.table2ID = table2.ID
or this:
update table1, table2
SET table1.table2ID = table2.ID
WHERE table1.name = table2.name
Let me know which one works for you best.
U can try this :
update TABLE1 set tabel2id = TABLE2.Id from TABLE1 s
inner join TABLE2 s on u.name = s.NAME
It worked for me..

Removing intermediate table

Given the following tables:
Table1
| id | intermediate_id |
Itermediate
| id |
Table2
| id | intermediate_id | table1_id|
How do i update Table2 with Table1.ids?
I'm trying the following:
update Table2
set table1_id =
(select table1.id
from table1
where table1.intermediate_id = table2.intermediate_id);
which gives me "ERROR: more than one row returned by a subquery used as an expression"
update Table2
set table1_id = table1.id
from table1
where table1.intermediate_id = table2.intermediate_id