Update column in Oracle table with value from another table with duplicates - sql

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
);

Related

Redshift: UPDATE statement using a LEFT JOIN returns "table name specified more than once" error

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

Boolean - Does ID Exist in Table?

I have two tables... A master ID table and a results ID table with only a few IDs from the master table. I'm looking to create the following SQL Query:
Select
A.ID
(Case when B.ID is in A.ID 1 Else 0 End) as is_found
From
master_table as A
LEFT JOIN results_table as B
ON A.ID = B.ID
The resulting table should have all IDs from master table with a boolean column saying if the ID was found in the results table. Thank you for your help!!
I would use case . . . exists:
Select mt.id,
(case when exists (select 1 from results_table rt where rt.id = mt.id) then 1 else 0 end) as is_found
From master_table ;
First, consider the case where results_table will have either zero or one matching row; in this case, the LEFT JOIN will always give one row for each ID, and B.ID will be NULL if there is no corresponding row in results_table.
We can therefore use a simple CASE to test this:
Select
A.ID,
CASE WHEN B.ID IS NOT NULL THEN 1 ELSE 0 END as is_found
From
master_table as A
LEFT JOIN results_table as B
ON A.ID = B.ID
If there may be more than one row in results_table for the same ID, the LEFT JOIN may in turn create several rows, one for each match.
The result of the CASE statement will be the same for all values of A.ID - if there are zero matches, it will occur once with value 0, and if there are one or more, it will always have the value 1. So we can simply take distinct values of the entire query:
Select Distinct
A.ID,
CASE WHEN B.ID IS NOT NULL THEN 1 ELSE 0 END as is_found
From
master_table as A
LEFT JOIN results_table as B
ON A.ID = B.ID

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);

Oracle Update Statement clarification required

I am updating a table based on values from another table using the Serial Number field as the common field to look up values. However from below 2 queries i get two different results. Can some one explain why the two outputs are different? Should not the update statement update 47200 records?
UPDATE TBL_SERIAL_NUMBER_MASTER A
SET (A.name) = (SELECT B.name
FROM TBL_DEVICE_LOCALITY B
WHERE A.SERIAL_NUMBER = B.SERIAL_NUMBER AND ROWNUM <=1 )
WHERE EXISTS ( SELECT 1
FROM TBL_DEVICE_LOCALITY
WHERE SERIAL_NUMBER = A.SERIAL_NUMBER
AND TBL_ODIN_DEVICE_LOCALITY.HOST_NAME IS NOT NULL );
Results int: 35,311 rows updated.
select count(*)
from TBL_SERIAL_NUMBER_MASTER A, TBL_DEVICE_LOCALITY B
WHERE A.SERIAL_NUMBER = B.SERIAL_NUMBER AND B.HOST_NAME IS NOT NULL;
Returns: Count = 47200
First, you should learn to use proper explicit JOIN syntax. So, the second query should be:
select count(*)
from TBL_SERIAL_NUMBER_MASTER A JOIN
TBL_DEVICE_LOCALITY B
ON A.SERIAL_NUMBER = B.SERIAL_NUMBER
where B.HOST_NAME IS NOT NULL;
You are getting the results you see because the two queries are not the same. Your results suggests that SERIAL_NUMBER is not unique in the B table, so the JOIN is multiplying rows. On the other hand, the UPDATE is updating rows in A, regardless of the number of matches in B.
To compare like to like, use:
select count(*)
from TBL_SERIAL_NUMBER_MASTER A JOIN
TBL_DEVICE_LOCALITY B
ON A.SERIAL_NUMBER = B.SERIAL_NUMBER
where exists (select 1
from TBL_DEVICE_LOCALITY B
where B.SERIAL_NUMBER = A.SERIAL_NUMBER AND
B.HOST_NAME IS NOT NULL
);
Or, if you have a unique/primary key column in A, then you can use:
select count(distinct A.??)
from TBL_SERIAL_NUMBER_MASTER A JOIN
TBL_DEVICE_LOCALITY B
ON A.SERIAL_NUMBER = B.SERIAL_NUMBER
where B.HOST_NAME IS NOT NULL;
Where ?? is the unique/primary key column.

Select non duplicate records from a hive join query

I have the following Hive query:
select *
from A
left outer join B
on A.ID = B.ID
where B.ID IS NULL
The result produces duplicate data but I need only non-duplicate records.
After some research, I tried the below query:
select *
from (
select *
from A
left outer join on B
where A.ID = B.ID AND B.ID IS NULL ) join_result
group by jojn_result.ID
It's showing an ambiguous column reference ID error.
I do not have the columns name of table A.
Please help me to identify the solution to this .
Thank you .
Hmmm . . . How about select:
Select A.*
from A left outer join
B
on A.ID = B.ID
where B.ID IS NULL;
I removed the B columns because they are not needed.
One of your join columns may have NULL values. Whenever there is NULL in any of the join key values, it will skip that column. Try replacing the NULL with some default value while joining using NVL or COALESCE. I was looking for same answer and saw your post here. But there was no solution. But since i found the solution I just wanted to post here so that someone can benefit.
select *
from A
left outer join B
on coalesce(A.ID,000) = coalesce(B.ID,000)
where B.ID IS NULL