SQL Query is updating with NULL values - sql

I am using Oracle and I am trying to update a table(A) with data from another table(B). Not every field in B has a value so I have a number of NULL entries. When I run the update it says 6000 rows updated. Now there are 6000 rows in table B, however for this query only 14 have data in. When I select count(*) from both tables for this value they both return 14 rows each. Why is it reporting that 6000 rows have been updated?
UPDATE
table1 A
SET
phone_work = (
SELECT B.phone_work
FROM table2 B
WHERE B.id = A.applicant_id)
WHERE EXISTS (
SELECT 1
FROM table2 B
WHERE B.id = A.applicant_id);
I have also tried the following and I get the same result:
UPDATE
table1 A
SET
phone_work = (
SELECT B.phone_work
FROM table2 B
WHERE B.id = A.applicant_id
AND B.phone_work is not null
)
WHERE EXISTS (
SELECT 1
FROM table2 B
WHERE B.id = A.applicant_id);
Why is it reporting the update of 6000 rows? When I change the fields but use the same syntax it reports updating of the exact number of rows I expect e.g. a count of table B has 86 entries in the NAME field and it reports 86 rows updated. It seems that with the phone_work field I am getting every null value being counted as an update.

Perhaps you want to check for the non-NULL value in the exists:
UPDATE table1 A
SET phone_work = (SELECT B.phone_work
FROM table2 B
WHERE B.id = A.applicant_id
)
WHERE EXISTS (SELECT 1
FROM table2 B
WHERE B.id = A.applicant_id AND B.phone_work IS NOT NULL
);

Try this:
UPDATE
(
SELECT A.phone_work Aphone, B.phone_work Bphone
FROM table2 B, table1 A
WHERE B.id = A.applicant_id AND B.phone_work IS NOT NULL
)
SET
Aphone = Bphone;
Source: Oracle SQL: Update a table with data from another table

Related

Oracle SQL Update column with data from another table using three conditional statements

Scenario:
I have two separate tables (table 1 and table 2)
I want to update a column from table one with the value of a column from table 2
Case 1:
I need columns b,c and d in table 1 to match b,c and d in table 2 before the update occurs
Case 2:
Column b in table 1 has a true value but Column b in table two references a look up (example in table 1 column b may have a value of blue but in table 2 column b has the value 14567 which is the id in a lookup table that references blue)
How would you accomplish getting this update completed?
create table ta as
select 1 ID,'Alex' Name , 27 age from dual
union
select 2 ID,'Bob' Name , 32 age from dual;
create table tb as
select 1 ID,'Alex' Name , 29 age from dual
union
select 5 ID,'Dick' Name , 24 age from dual;
update ta a
set a.age = (select b.age from tb b where a.id=b.id and b.name=a.name)
where exists ( select 1 from tb where a.id=tb.id and a.name = tb.name);
Assuming table lookup has columns b (corresponding to t2.b) and col_x (corresponding to t1.b), you could do something like this, using the merge statement:
merge into t1
using (
select t2.a, l.col_x, t2.c, t2.d
from t2 join lookup l on t2.b = l.b
) s
on (t1.b = s.col_x and t1.c = t2.c and t1.d = t2.d)
when matched then update
set t1.a = s.a
;

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

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

select sql query to merge results

I have a table old_data and a table new_data. I want to write a select statement that gives me
Rows in old_data stay there
New rows in new_data get added to old_data
unique key is id so rows with id in new_data should update existing ones in old_data
I need to write a select statement that would give me old_data updated with new data and new data added to it.
Example:
Table a:
id count
1 2
2 19
3 4
Table b:
id count
2 22
5 7
I need a SELECT statement that gives me
id count
1 2
2 22
3 4
5 7
Based on your desired results:
SELECT
*
FROM
[TableB] AS B
UNION ALL
SELECT
*
FROM
[TableA] AS A
WHERE
A.id NOT IN (SELECT id FROM [TableB])
I think this would work pretty neatly with COALESCE:
SELECT a.id, COALESCE(b.count, a.count)
FROM a
FULL OUTER JOIN b
ON a.id = b.id
Note - if your RDBMS does not contain COALESCE, you can write out the function using CASE as follows:
SELECT a.id,
CASE WHEN b.count IS NULL THEN a.count
ELSE b.count END AS count
FROM ...
You can write a FULL OUTER JOIN as follows:
SELECT *
FROM a
LEFT JOIN b
ON a.id = b.id
UNION ALL
SELECT *
FROM b
LEFT a
ON b.id = a.id
You have to use UPSERT to update old data and add new data in Old_data table and select all rows from Old_data. Check following and let me know what you think about this query
UPDATE [old_data]
SET [count] = B.[count]
FROM [old_data] AS A
INNER JOIN [new_Data] AS B
ON A.[id] = B.[id]
INSERT INTO [old_data]
([id]
,[count])
SELECT A.[id]
,A.[count]
FROM [new_Data] AS A
LEFT JOIN [old_data] AS B
ON A.[id] = B.[id]
WHERE B.[id] IS NULL
SELECT *
FROM [old_data]

Update column of Table B based on column of Table A

I have a huge stored procedure and I am trying to optimize it .
I have a temporary table A , with column Id.
I have a main table B with columns Id & a boolean field Test
For all Id's in Table A , I need to make the Test = 1 in Table B.
example :
A
Id
--
1
2
3
I need to get table B as follows.
I already have the Id field in Table B , I only need to update the
Test Column
B
Id Test
-- ----
1 1
2 1
3 1
4
5
6
I am currently looping through Table A using a while loop and for each Id
I am updating the Test column in Table B .
WHILE (1 = 1)
BEGIN
-- Exit loop if no more Transactions
IF ##ROWCOUNT = 0 BREAK;
Update [B]
set Test = 1
where Id = (SELECT TOP 1 Id
FROM #B
WHERE Id > #Id1
ORDER BY Id)
END
PS : #Id1 is the input parameter of the stored procedure.
I cannot think of any other efficient way of doing it, but
my query is taking a lot of time to run..
Please let me know if there is a better way of doing the same thing.
This is pretty straight forward.
UPDATE [B]
SET [TEST] = 1
FROM [B] INNER JOIN [A]
ON [A].ID = [B].ID
Another alternative:
UPDATE b SET test = 1
FROM dbo.TableB AS b
WHERE EXISTS (SELECT 1 FROM dbo.TableA WHERE ID = b.ID);
You don't need to loop for this, just join those tables
UPDATE B
SET B.Test = 1
FROM TableB B
INNER JOIN TableA A
ON A.Id = B.ID
Here is an sqlfiddle with a live demo.
You can use in to find the records to update:
update b
set Test = 1
where Id in (select Id from #A)
Another alternative is to join the tables:
update x
set Test = 1
from b as x
inner join #A as a on a.id = x.id
If I'm understanding your question correctly, all you need to do is join A and B.
UPDATE TableB SET test = 1
FROM TableB b
INNER JOIN TableA a ON a.id = b.id
WHERE b.ID > #Id1
Basically you're looking to update everywhere where TableA and TableB intersect.
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

Update a table with records from another table

I am trying to update my table 1 with some field value from table 2 based on a condition. But am unable to get the proper query. Here's the condition:
I have a table 1 with date field which should be updated from table 2 date field. The condition is that the id of table 1 should be equal to id of table 2 (Table 2 has id of table 1 as FK). Another condition should be there is a varchar field in table 2 which should have specific value, say "Test". Wherever the value of field in table 2 is "Test" I want to update the date of with that record in table 1 date field. But there is another catch. It may be possible that more than 1 records for same id in table 2 can have value as "Test"
I was trying the query as:
UPDATE A
SET A.Date = Max(B.[Date])
FROM Table1 A
INNER JOIN Table2 B ON A.ID = B.FK_ID
WHERE (B.Changed LIKE 'Test')
AND A.Date IS NULL
But this is not working as sql does not allow Max in update when there is no group by. Please help. A bit urgent.
You need to create another inner join where the ID's of Table1 are coupled with the maximum dates of Table2 like so:
UPDATE Table1
SET Date = BDate.MaxDate
FROM Table1 A
INNER JOIN Table2 B ON A.ID = b.FK_ID
INNER JOIN (
SELECT A.ID, [MaxDate] = MAX(B.Date)
FROM Table1 A
INNER JOIN Table2 B ON A.ID = b.FK_ID
GROUP BY A.ID
) BDate ON BDate.ID = A.ID
WHERE B.Changed LIKE 'Test'
A.Date IS NULL
You could always use subqueries:
UPDATE Table1 a SET
[Date] = (SELECT MAX([Date]) FROM Table2 b WHERE a.ID = b.FK_ID AND b.Changed LIKE 'Test')
WHERE [Date] IS NULL