I need to update values in a table from another table and if they don't exist it must be inserted. So I saw this example in here
UPDATE Table1 SET (...) WHERE Column1='SomeValue'
IF ##ROWCOUNT=0
INSERT INTO Table1 VALUES (...)
Now I would like to do this but instead of a where clause with a value i need to check if columns match on another table.
Something like
UPDATE t1
SET
t1.status = t2.status
FROM
table1 t1, table2 t2
WHERE t1.reference = t2.reference and t1.section = t2.section
I assume this is very bad in terms of performance and i would like to hear some other suggestions.
EDIT
Also please, if you can, i would like to hear why the approach you give is better than using a merge or a join for example. Much appreciated.
RESULT
Here is the approach i went for after checking how bad merge performance is compared to an update then insert and trying to test everyones approach this is what i decided for, basically uses a bit of everyone's answer
UPDATE C
SET
C.ConsumoWeek01 = M.ConsumoWeek01
FROM
Consumos AS C
INNER JOIN #tempTable M
ON C.Referencia = M.Referencia
AND C.UAP = M.UAP
INSERT INTO
Consumos
SELECT *
FROM #tempTable M
WHERE NOT EXISTS
(
SELECT 1 FROM Consumos C
WHERE C.Referencia = M.Referencia
AND C.UAP = M.UAP
)
Try this
UPDATE t1
SET
t1.status = t2.status
FROM
table1 t1
WHERE NOT EXISTS (SELECT 1 FROM table2 t2
WHERE t1.reference = t2.reference
and t1.section = t2.section )
use not exists
UPDATE t1
SET
t1.status = t2.status
FROM
table1 t1 where not exists( select 1 from table2 t2 where t1.=ref=t2.ref and t1.section=t2.secction)
Use merge statement:
MERGE INTO Table1 T1
USING
(
SELECT * FROM Table2
) T2
ON
(
T1.reference = T2.reference AND
T1.section = T2.section
)
WHEN MATCHED THEN
--UPDATE STATEMENT
WHEN NOT MATCHED THEN
--INSERT STATEMENT
Your method is fine just use standard explicit join syntax instead of old style with comma separate :
update t1
set . . .
from table t1 inner join
table t2
on t1.reference = t2.reference and t1.section = t2.section;
Related
I have three tables
table1 -> xt1, yt1, zt1;
table2 -> xt2
table3 -> yt3, zt3
SELECT xt1, yt1, zt1
From table1, table3
Where xt1
NOT IN
(SELECT DISTINCT table1.xt1 FROM table2 INNER JOIN table1 ON
table1.xt1 = Replace(table2.xt2,',',''))
And table1.yt1 = table3.yt3
AND table1.zt1 = table3.zt3
it is working correctly but i take long time.
if i replace NOT IN with Not exists it return empty set.
SELECT xt1, yt1, zt1
From table1, table3
Where Not exists
(SELECT DISTINCT table1.xt1 FROM table2 INNER JOIN table1 ON
table1.xt1 = Replace(table2.xt2,',',''))
And table1.yt1 = table3.yt3
AND table1.zt1 = table3.zt3
the results of the second select should be 6 rows but it returns notiong with not exists.
also if i tried to change the compare part to
table1.xt1 != Replace(table2.xt2,',','') and remove the NOT IN
select it get outof memory error.
So is this the best way to write my query and why it return empty set with Not exists
thank you.
Ok, first of all, I changed your implicit join to an explicit one. Then I fixed the NOT EXISTS so it correlates to the outer table1:
SELECT t1.xt1, t1.yt1, t1.zt1
FROM table1 AS t1
INNER JOIN table3 AS t3
ON t1.yt1 = t3.yt3
AND t1.zt1 = t3.zt3
WHERE NOT EXISTS ( SELECT 1
FROM table2 AS t2
INNER JOIN table1 AS t1_1
ON t1_1.xt1 = REPLACE(t2.xt2,',','')
AND t1_1.xt1 = t1.xt1) ;
which can be simplified further to:
SELECT t1.xt1, t1.yt1, t1.zt1
FROM table1 AS t1
INNER JOIN table3 AS t3
ON t1.yt1 = t3.yt3
AND t1.zt1 = t3.zt3
WHERE NOT EXISTS ( SELECT 1
FROM table2 AS t2
WHERE t1.xt1 = REPLACE(t2.xt2,',','')
) ;
You need to select IN or exist depending upon the size of inner query. when there is a outer query and inner-sub-query, if the result of sub query is small, In is preferred as outer query is selected based upon result of sub-query.
if the result of sub-query is large, exist is preferred as outer query is evaluated first.
I need to insert 3 columns from one table to another, using JOIN by 3 fields: name, surname and age
I need update column status, status1 and status2 in table_2 with values from table_1
IF
table_1.name = table_2.name
table_1.surname = table_2.surname
table_1.age= table_2.age
UPDATE t2
SET
t2.[status]=t1.[status]
,t2.[status1]=t1.[status1]
,t2.[status2]=t1.[status2]
FROM [table_1] t1
INNER JOIN [table_2] t2
ON (t1.name=t2.name AND t1.surname=t2.surname AND t1.age=t2.age)
As you mentioned in comments that these table from different databases, then please change only the two line like.
FROM [yourDataBase1Name].[dbo].[table_1] t1
INNER JOIN [yourDataBase2Name].[dbo].[table_2] t2
Just update the table with Join.
it will be something like this:
UPDATE t2
SET t2.status = t1.status,
t2.status1 = t1.status1,
t2.status2 = t1.status2
FROM t2 JOIN t1 on (t1.first_name = t2.first_name AND t1.last_name = t2.last_name AND t1.age = t2.age);
Look here for more information:SQL update query using joins
SQL Fiddle: http://sqlfiddle.com/#!3/b3951/1
I am not sure if I've missed to search properly, but I couldn't get the exact question as mine
This is something similar but not exact
https://stackoverflow.com/questions/11533636/determining-which-table-to-join-to
Actually I want to decide with which table to join based on the parameter passed to stored procedure, case when didn't work
Kind of
select * from Table1
left join (case when #Parameter<>NULL Then Table2 else Table3 end) final
on Table1.Col1 = final.Col1
Table2 and Table3 has same structure
I can think of a few of options:
1: IF ... ELSE
IF #Parameter IS NULL
SELECT *
FROM T1
INNER JOIN T2 ON T1.ID = T2.ID
ELSE
SELECT *
FROM T1
INNER JOIN T3 ON T1.ID = T3.ID
2: Dynamic T-SQL
DECLARE #SQL NVARCHAR(MAX);
SELECT #SQL = N'SELECT *
FROM T1
INNER JOIN ' + CASE WHEN #Parameter IS NULL THEN N'T2 t' ELSE N'T3 t' END
+ N' ON T1.ID = t.ID';
EXEC sp_executesql #SQL;
3: UNION ALL and subquery.
SELECT *
FROM T1
INNER JOIN
(
SELECT *
FROM T2
WHERE #Parameter IS NULL
UNION ALL
SELECT *
FROM T3
WHERE #Parameter IS NOT NULL
) t ON T1.ID = t.ID
For this last one you'd have to check the plan the optimiser creates to see if it's OK performance wise.
It seems like you're looking for code reuse, so maybe option 2 is your best one. T-SQL doesn't really lend itself to this sort of polymorphism but you can use workarounds in some cases.
Taking a step back, one question to ask is, if the tables have the same structure, maybe you should just use one table? Then you could use #Parameter to just filter the rows you require instead of trying to create dynamic queries.
It's also worth noting that in situations like this you could handle the code-generation at the application layer with ORMs and the like.
Try this:
select *
from (
select data.*,
case when selection=1 then t1.ExtraField
when selection=2 then t2.ExtraField
when selection=3 then t3.ExtraField
else NULL
end as ExtraField
from data
left join t1 on t1.key = data.key and selection=1
left join t2 on t2.key = data.key and selection=2
left join t3 on t3.key = data.key and selection=3
) T
where ExtraField is not NULL
Done with this
SELECT PA.`module_id` as usertype, PA.module_pk_id, (
CASE PA.`module_id`
WHEN '0'
THEN pea.`name`
ELSE CONCAT(u.`first_name`, " ",u.`last_name`)
END
) as name
FROM `placements_approvers` PA
LEFT JOIN
placements_external_approvers pea
ON
PA.module_pk_id = pea.placement_external_approver_id AND PA.`module_id` = 0
LEFT JOIN
users u
ON
PA.module_pk_id = u.user_id AND PA.`module_id` != 0
WHERE PA.placement_id = '494' AND PA.approver_type = 1
I am new to SQL, using Microsoft SQL Server Management Studio.
I am trying to write a SQL statement that performs an update after two tables are joined.
I have two tables: myTable1 and myTable2. Both share a field MyID, which is going to be the field that I join on. myTable1 contains a column called BitToUpdate. And MyTable2 contains a column called BitToCheck.
I want to set BitToUpdate in myTable1 to be 1 where BitToCheck in myTable2 is 1 as well.
Here is what I have:
SELECT M.MyID, BitToUpdate, BitToCheck
INTO #temp_table
FROM myTable1 as T1
LEFT JOIN myTable2 as T2
ON M.MyId = PO.MyId
So first I tried to join the two tables myTable1 and myTable2 on their IDs, and store the result in a temporary table.
Next, I want to update BitToUpdate to be 1 where BitToCheck is 1.
So to do that in the temporary table, I have:
UPDATE #temp_table
SET
`BitToUpdate` = 1
WHERE
`BitToCheck` = 1
This updates the BitToUpdate successfully in #temp_table. However, when I do a select on myTable1, I find that BitToUpdate is not changed. I suppose this makes sense as #temp_table isn't really a "pointer"....
But what would be the correct way to approach this join and update?
You don't need to use a LEFT JOIN here, since you are checking on a condition from table 2, so an INNER JOIN should be better here.
UPDATE T1
SET T1.BitToUpdate = 1
FROM myTable1 T1
INNER JOIN myTable2 T2
ON T1.MyId = T2.MyId
WHERE T2.BitToCheck = 1
What you are doing in your first query is updating a temp table named #temp. the updates never go to the actual table myTable1 or mayTable2. To update records while joining with other tables try this:
UPDATE T1
SET T1.BitToUpdate = 1
FROM myTable1 as T1
LEFT JOIN myTable2 as T2 (ON T1.MyId = T2.MyId)
WHERE T2.BitToCheck = 1
--SELECT M.MyID, BitToUpdate, BitToCheck
--INTO #temp_table
update t1
set t1.BitToUpdate = 1
FROM myTable1 as T1
LEFT JOIN myTable2 as T2
ON t1.MyId = t2.MyId
where t2.bittocheck = 1
UPDATE T1
SET BitToUpdate=1
FROM myTable1 T1
LEFT JOIN myTable2 T2
ON T1.MyId=T2.MyId
WHERE T2.BitToCheck=1
I'm trying write a routine in SQL Server that, when run, would traverse specified tables and, if a specific column contains a value, update another value. In pseudo code:
select * from table1
if column1 = true
{
update table2.column1 with value where table2.column2.value = table1.column2.value
}
Basically, traverse table1 and if the value in a specific column is true, update the value of another table's column1 where that row's column2 matches table1's column2
Thanks
You don't need the IF, just use a WHERE clause:
UPDATE T2
SET t2.Column1 = 'blah'
FROM Table2 t2
INNER JOIN Table1 t1
ON t1.value = t2.value
WHERE t1.column1 = 'True'
Not sure I fully understand your requirement, but if you want update all the values using a single update statement this might do:
update table2 set column1 =
(select column1 from table1 t1
where t1.column2 = table2.column2
)
where exists
(select * from table1 t1
where t1.column2 = table2.column2 and t1.column1 = true
)
It could be written to avoid having the 2nd subselect (the EXISTS clause) but the solution is rather dialect-specific. This one is, I believe, more likely to be accepted in an unknown dialect. (Except for the word "true" ... substitute the value you want, there. )