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
Related
I have an UPDATE statement in Redshift that I'd like to use the LEFT JOIN method to identify records that don't exist in the second table. The statement keeps returning the "table name specified more than once" error. I understand I can use different methods such as NOT IN with a subquery but I'd like to learn how can I adapt this script in PostgreSQL using LEFT JOIN approach. Thank you in advance.
UPDATE A
SET A.column_Name = 'Y'
FROM tbl_A A
LEFT JOIN tbl_B B
ON A.Mathcing_Column_Name = B.Matching_Column_Name
WHERE B.Matching_Column_Name is NULL
Use NOT EXISTS instead:
UPDATE tbl_A A
SET column_Name = 'Y'
WHERE NOT EXISTS (SELECT 1
FROM tbl_B B
WHERE A.Matching_Column_Name = B.Matching_Column_Name
);
Try this. (it's working)
with temp AS
(
SELECT A.* FROM tbl_A A
LEFT JOIN tbl_B B
ON A.Mathcing_Column_Name = B.Matching_Column_Name
WHERE B.Matching_Column_Name is NULL
)
UPDATE tbl_A C SET column_Name = 'Y'
from temp D
where C.id=D.id
I am trying to update the column (REPT_IND) from table A to the value in table B where A.ID = B.ID and some conditions in table B.
There are some duplicates in table B, but nonetheless the REPT_IND is the same and I still need the value.
How can I do this on Oracle? Any tips are appreciated thank you!
The Following code has the Error:
ORA-01427: single-row subquery returns more than one row
Code:
UPDATE A
SET REPT_IND= (
SELECT B.REPT_IND
FROM B
INNER JOIN A
ON B.ID = A.ID
where A.ID = B.ID
and B.job_type = 'P'
and B.FT_PT is not null
);
You can try also merge statement:
merge into a
using (
select a.id,max(b.rept_ind) rept_ind
from a left join b on a.id=b.id
where b.job_type = 'p'
and b.ft_pt is not null
) b
on (a.id=b.id)
when matched then update
set a.rept_ind=b.rept_ind;
Or if you do not want to set a.rept_ind to null if there is no relevant rows in b:
merge into a
using (
select b.id, max(b.rept_ind) rept_ind
from b
where
b.job_type = 'p'
and b.ft_pt is not null
group by b.id
) b
on (a.id=b.id)
when matched then update
set a.rept_ind=b.rept_ind;
Consider:
update a
set rept_ind= (
select max(b.rept_ind)
from b
where
a.id = b.id
and b.job_type = 'p'
and b.ft_pt is not null
);
There is no need to join table a again in the subquery - a correlation clause is enough. And you can work around possible duplicates by turning on aggregation, which guarantees that only one row will be returned.
You could also use select distinct instead of select max(...) in the subquery. This is somehow more accurate since it does ensure that the multiple rows have the same rept_ind (it they do not, then you would still get the ORA-01427 error).
Just use a correlated subquery . . . and do not repeat the table reference in the subquery:
UPDATE A
SET REPT_IND = (SELECT B.REPT_IND
FROM B
WHERE B.ID = A.ID AND
B.job_type = 'P' AND
B.FT_PT is not null AND
rownum = 1
);
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.
I have the following query.
UPDATE A SET b = (SELECT b FROM B WHERE A.a_id = B.a_id AND B.value = ?)
This might fill A with NULL values if no a_id exists in B where value = ?. but this is okay, because before executing this query, it is certain that A.b contains only NULL values to begin with.
However, I need the number of updated columns to reflect the number of updates performed. So I changed it into this:
UPDATE A SET b = (SELECT b FROM B WHERE A.a_id = B.a_id AND B.value = ?)
WHERE EXISTS (SELECT b FROM B WHERE A.a_id = B.a_id AND B.value = ?)
I don't like this solution, because now I have duplicate code and have to fill the parameter multiple times. This gets even uglier when the where clause gets more complicated.
Is there a way to get rid of this duplicate code?
(BTW I'm on Oracle 10, but I prefer DB independent solutions)
Updat using an inner join
UPDATE A
INNER JOIN B ON A.a_id = B.a_id
SET A.b = B.b
WHERE B.value = ?
If that isn't allowed with your particular RDBMS, perhaps you could SELECT the old and new values into an aliased table expression and update using that. See Update statement with inner join on Oracle
I need to update a value in a table if a specific value exists in another table.
i.e.
update table1
set value1=3
where table2.value2='Y'
There is a key ref1 in both tables- how do i use this key to link these together? Many thanks!
update table1
inner join table2 on table1.ref1 = table2.ref1
set value1 = 3
where table2.value2 = 'Y'
you can write a join between both tables and then make the update from the join.
Something like:
update tableA
set column = b.value
from tableA a
join tableB on a.key = b.key