How to link tables in an update statement using Oracle? [duplicate] - sql

This question already has answers here:
Update statement with inner join on Oracle
(15 answers)
Closed 8 years ago.
I need to update all the rows on table A, where A.id = B.id and B.code is some value.
Something like:
UPDATE table_a
SET processed = 'Y'
WHERE table_a.id = table_b.id AND
table_b.code = 'ABC';
Does anyone know the correct way to do this?
Thanks!

Here are quick workaround for your problem.
UPDATE
(
SELECT
a.processed, a.id
FROM
table_a a,
table_b b
WHERE
a.id = b.id
AND
b.code = 'ABC'
) u
SET u.processed = 'Y'
OR
UPDATE table_a a
SET a.processed = 'Y'
WHERE a.id IN
(SELECT b.id FROM table_b b WHERE b.code = 'ABC')
Hope this might Help!

You have to reference second table before you can use it. You can use a subselect:
UPDATE table_a SET processed = 'Y'
WHERE table_a.id = (SELECT table_b.id FROM table_b WHERE table_b.code = 'ABC');
The subselect returns a list of ids from table_b fulfilling the condition table_b.code = 'ABC'. Update will effect those rows in table_a with table_a.id in the list from subselect.

Related

Getting error when doing an update query using joins [duplicate]

This question already has answers here:
How to do an update sql query using a sub select query?
(2 answers)
Closed last year.
UPDATE A
SET foo = 'bar',
car = 'bmw'
FROM TableA A
JOIN TableB B
ON A.col1 = B.colx
AND A.STATUS = B.STATUS
WHERE A.nbr = '1234'
and A.STATUS IN (K,Y)
and A.FILE_TYPE = 'R'
I am trying to use the update function above but I keep getting the error it is not properly ended when I try to run it. Can someone tell me where the syntax error is?
.
In the Oracle database, when updating a table from another table, it's often easier to use the MERGE statement.
MERGE INTO TableA A
USING TableB B ON (
A.col1 = B.colx
AND A.STATUS = B.STATUS
AND A.nbr = 1234
AND A.STATUS IN (K,Y)
AND A.FILE_TYPE = 'R'
)
WHEN MATCHED THEN UPDATE
SET foo = 'bar'
, car = 'bmw';
In Oracle you can not update a join query. You may only update a table (and im some cases a view or a subquery).
Fortunately you can simple rewrite your update without the join by passing the condition in the where clause.
update TableA a
set foo = 'bar',
car = 'bmw'
WHERE a.nbr = '1234'
and a.STATUS IN ('K','Y')
and a.FILE_TYPE = 'R'
and (col1, status) in (select colx,status from tableB);
This is the simplest solution for you problem as described.
Note if you realy needs a join, e.g. if you need to update the columns of the tableA with the columns of the tableB such as
UPDATE A
SET a.foo = b.foo,
a.car = b.car
....
You may use in Oracle an updatable join view as follows
update (
select a.*, b.foo new_foo, b.car new_car
FROM TableA A
JOIN TableB B
ON A.col1 = B.colx
AND A.STATUS = B.STATUS
WHERE A.nbr = '1234'
and A.STATUS IN ('K','Y')
and A.FILE_TYPE = 'R'
)
set foo = new_foo,
car = new_car
Note that the join query is enclosed in parenthesis to get the rigth syntax.
Note also that the tableB must have a primary key (or unique index) on the columns colx,status to be able to update. Otherwise you get exception ORA-01779: cannot modify a column which maps to a non key-preserved table

MSSQL How to copy data from one table to another with a condition

I'm trying to update table a with data from some of the columns in table b. Column names are matching in both tables, cannot figure out the syntax, can anyone help?
This is what I want to do (expressed out-of-syntax):
UPDATE table_a
SET table_a.col1 = table_b.col1, table_a.col2 = table_b.col2
WHERE table_a.id = table_b.id
Maybe (probably) I would need some kind of JOIN-clause, but I haven't gotten my head around those yet.... :-/
You can update your table using a JOIN of the two tables:
UPDATE table_a a
INNER JOIN table_b b ON a.id = b.id
SET a.col1 = b.col1, a.col2 = b.col2
I see you are on MYSQL. Not sure if the version above works. If not, try:
UPDATE table_a a
INNER JOIN table_b b
SET a.col1 = b.col1, a.col2 = b.col2
WHERE a.id = b.id
Ok, so I found it myself... :-)
MERGE (without using the WHEN NOT MATCHED clause)is the answer to my problem.
My solution:
MERGE INTO table_a
USING table_b
ON a.id=b.id
WHEN MATCHED THEN UPDATE SET
col1 = b.col1, col2 = b.col2;

Why this Join-Update query update all value?

I made some mistake and all values of a column are updated.
I did this in SQL Server 2008 R2.
I should have run some query like this:
UPDATE TABLE_A
SET FEEL = 'HAPPY'
FROM TABLE_A A
INNER JOIN TABLE_B B ON A.SN = B.SN
WHERE B.WEATHER = 'SUNNY';
However, I made a mistake and ran this:
UPDATE TABLE_A
SET FEEL = 'HAPPY'
FROM TABLE_C A
INNER JOIN TABLE_B B ON A.SN = B.SN
WHERE B.WEATHER = 'SUNNY';
and even TABLE_C has column of [SN].
I expected that this query update FEEL of TABLE_A as 'HAPPY' where WEATHER of TABLE_B is 'SUNNY' with inner join between two tables, but every value of column FEEL is updated to 'HAPPY'.
What means Update A set ~ from c in SQL Server and when it should be used? And why "inner-join" updates all values?
This query:
UPDATE TABLE_A
SET FEEL = 'HAPPY'
FROM TABLE_C A INNER JOIN
TABLE_B B
ON A.SN = B.SN
WHERE B.WEATHER = 'SUNNY';
is saying to update all rows in TABLE_A that match the conditions in the ON and WHERE clauses. But, none of those conditions involve TABLE_A. So, nothing is being filtered. Actually, what you are doing is equivalent to:
UPDATE AA
SET FEEL = 'HAPPY'
FROM TABLE AA CROSS JOIN
TABLE_C A INNER JOIN
TABLE_B B
ON A.SN = B.SN
WHERE B.WEATHER = 'SUNNY';
This is a bit of weirdness in the UPDATE.
When you do:
UPDATE TABLE_A
SET FEEL = 'HAPPY'
FROM TABLE_A A INNER JOIN
TABLE_B B
ON A.SN = B.SN
WHERE B.WEATHER = 'SUNNY';
SQL Server makes an exception to the rule that an alias always replaces the table reference. It still allows TABLE_A in the UPDATE to refer to A. So, there is no CROSS JOIN.
Personally, I consider this broken-ness, because a table alias should always replace the table reference. The developers at Microsoft think otherwise. And there is no standard that guides this syntax.
If you have a FROM clause, I recommend that always use table aliases.
UPDATE A
SET FEEL = 'HAPPY'
FROM TABLE_A A INNER JOIN
TABLE_B B
ON A.SN = B.SN
WHERE B.WEATHER = 'SUNNY';

SQL: set value with condition

I have some Problem, there are two Tables, they communicate with the value ID.
Now I will set the value from Column a in Table A with the value 'Nein', but only if the value of the column b in Table B is '0' and
if a.id = b.id.
How can I do that?
Thanks
You'll need to make a Join in the Update Statement like:
UPDATE a set ColumnA='Nein' from TableA a inner join TableB b on a.id=b.id WHERE b.ColumnB='0'
please try the below query . Since there here i am not sure that id is primary column in table , i have used "in" clause .
update A
set A.a ='Nein'
where A.id in ( select A.id from A ,B
where A.id = B.id and B.b='0')
Try with
update A a set a.a='Nein'
where a.id in (select b.id from B b where B.b='0' and a.id=b.id);

In SQL, adding a set of values corresponding on a join

Let's say that I have Table_A contain:
ID OldValue
3 16
1 5
and Table_B contains
ID Value OldValue
1 2 NULL
2 4 NULL
3 8 NULL
and that I want to insert OldValues from Table_A into Table_B where the IDs equal resulting in :
updated Table_B
ID Value OldValue
1 2 5
2 4 NULL
3 8 16
Is there a set based way of doing this without using a cursor? In real life this will be going on very large tables and cursors, as we all know are slow. Perhaps some sort of Merge?
I'm on SQL Server 2008
Update Table_B
Set OldValue = A.OldValue
From Table_A As A
Join Table_B As B
On B.ID = A.ID
You want an "update from"
UPDATE B
SET B.OldValue = A.OldValue
FROM Table_B B
INNER JOIN Table_A ON B.ID = A.ID
Generally I write this as a select, then once i get the result I convert it over to the update.
Simple:
update x set OldValue = a.OldValue
from Table_B x
join Table_A a on x.ID = a.ID
Use a join:
UPDATE TABLE_B
SET OLDAVLUE=A.OLDVALUE
FROM TABLE_B B
LEFT JOIN TABLE_A A ON B.ID=A.ID
Perhaps some sort of Merge?
Indeed. The following is Standard SQL that is supported on SQL Server 2008:
MERGE INTO Table_B
USING Table_A
ON Table_B.ID = Table_A.ID
WHEN MATCHED THEN
UPDATE
SET OldValue = Table_A.OldValue;