How to update a table with null values with data from other table at one time? - oracle

I have 2 tables - A and B . Table A has two columns, pkey (primary key) and col1. Table B also has two columns, pr_key (primary key but not a foreign key) and column1. Both tables have 4 rows. Table B has no values in column1, while table A has column1 values for all 4 rows. So my data looks like this
Table A
pkey col1
A 10
B 20
C 30
D 40
Table B
pr_key column1
A null
B null
C null
D null
I want to update table B to set the column1 value of each row equal to the column1 value of the equivalent row from table A in a single DML statement.

Should be something like that (depends on SQL implementation you use, but in general, the following is rather standard. In particular should work in MS-SQL and in MySQL.
INSERT INTO tblB (pr_key, column1)
SELECT pkey, col1
FROM tblA
-- WHERE some condition (if you don't want 100% of A to be copied)
The question is a bit unclear as to the nature of tblB's pr_key, if for some reason this was a default/auto-incremented key for that table, it could just then be omitted from both the column list (in parenthesis) and in the SELECT that follows. In this fashion upon insertion of each new row, a new value would be generated.
Edit: It appears the OP actually wants to update table B with values from A.
The syntax for this should then be something like
UPDATE tblB
SET Column1 = A.Col1
FROM tblA AS A
JOIN tblB AS B ON B.pr_key = A.pkey

This may perform better:
MERGE INTO tableB
USING (select pkey, col1 from tableA) a
ON (tableB.pr_key = a.pkey)
WHEN MATCHED THEN UPDATE
SET tableB.column1 = a.col1;

It sounds like you want to do a correlated update. The syntax for that in Oracle is
UPDATE tableB b
SET column1 = (SELECT a.column1
FROM tableA a
WHERE a.pkey = b.pr_key)
WHERE EXISTS( SELECT 1
FROM tableA a
WHERE a.pkey = b.pr_key )
The WHERE EXISTS clause isn't necessary if tableA and tableB each have 4 rows and have the same set of keys in each. It is much safer to include that option, though, to avoid updating column1 values of tableB to NULL if there is no matching row in tableA.

Related

If oracle table1 is empty then output table2 else output table1 itself; No columns on both the tables are common

I have two different table:
Table1, Table2.
Two tables have different columns and nothing in common. What I am looking to get is
if Table1 is empty/null then
output Table2
else
output table1
Is it possible to get it done in Oracle? Any leads would be appreciated.
Accordingly to your phrase:
if Table1 is empty/null then output Table2 else output table1
I think the solution is (I briefed Table1, Table2 by A, B respectively ):
--I created this tables to test the solution
create table A( id number, val varchar2(5));
create table B( code varchar2(5), event_dt date);
insert into b(code, event_dt)
values ('test', sysdate);
--query(1)
select b.code, to_char(b.event_dt,'yyyy-mm-dd')
from b
where not exists (select 1 from a)
union
select to_char(id), to_char(val)
from a
;
--now insert data on the other table (to test purposes)
insert into A(id, val)
values(1, 'TestA');
--run the query(1) again
The key is "union", kind of repeat your query when the first portion deals to no data
found.
Please remember to CAST your columns to achieve the same DATA-TYPES required by UNION
Best regards.

Insert data into one table from another table avoiding duplicates

I've got a table as follows
Table1
ID Name Tag
-----------------
1 N1 2.1
2 N2 3.5
3 N1 3.5
4 N3 8.1
I create a new table Table2 with ID and Name (unique constraint) and I want to insert Table1's contents into Table2 avoiding duplicates, in the sense that I want only 1, 2 and 4 from Table1 in Table2.
I've tried this but it doesn't seem to work and I get the unique constraint error (ORACLE SQL)
INSERT INTO TABLE2 (ID, NAME)
SELECT ID, NAME
FROM TABLE1
WHERE NAME NOT IN (SELECT NAME FROM TABLE2);
Please can someone point me in the right direction?
Sorry for not making myself clear. Table2 is a brand new table. I want the first values inserted, the following duplicates should be ignored. So in my case, N1, N2 get inserted, N1 is dupe so it is ignored, N3 is inserted
OK - from your description, I understand table t2 is currently empty, and you want to copy the rows where id is in (1, 2, 4) from table t1 to table t2.
Why your code fails:
You seem to believe that the condition is applied to the first row in t1, it passes so it is inserted into t2, then the condition is applied to the second row in t1 (using what is already inserted in t2), etc. - and you don't understand why there is any attempt to insert ALL the rows from t1 into t2. Why doesn't the third row fail the WHERE clause?
Good question! The reason is that operations are done on a SET basis. The WHERE condition uses table t2 AS IT WAS before the INSERT operation began. So for ALL rows, the WHERE clause compares to an empty table t2.
How to fix this... Decide which id you want to add when there are duplicate names. For example, one way to get the result you said you wanted is to select MIN(id) for each name. Moreover, you still want to check if the name exists in t2 already (since you may do this again in the future, when t2 is already partially populated).
insert into t2 ( id, name )
select min(id), name
from t1
where name not in (select name from t2)
group by name
;
You can try it bother....!
Insert into tb2(Field1, Field2)
SELECT Field1, Field2
FROM tb1
WHERE NOT EXISTS (SELECT Field1 FROM tb1) ;
This is how I understood the question:
SQL> create table table2
2 (id number,
3 name varchar2(2),
4 tag number,
5 constraint pk_t2 primary key (id, name)
6 );
Table created.
SQL>
SQL> insert into table2 (id, name, tag)
2 with test (id, name, tag) as
3 (select 1, 'N1', 2.1 from dual union
4 select 2, 'N2', 3.5 from dual union
5 select 3, 'N1', 3.5 from dual union
6 select 4, 'N3', 8.1 from dual
7 )
8 select min(id), name, max(tag)
9 from test
10 group by name;
3 rows created.
SQL>
SQL> select * from table2 order by id;
ID NA TAG
---------- -- ----------
1 N1 3,5
2 N2 3,5
4 N3 8,1
SQL>
When we need to unique any two or more column we have to create unique index.
Run this query
ALTER TABLE TABLE2 ADD UNIQUE unique_index( id, name);
and then
INSERT INTO TABLE2 (id,name,tag) VALUES(1, "N1", 3.5 )
ON DUPLICATE KEY UPDATE tag=3.5
this will also help to update new tag
Try to check if the id and name from Table1 is doesn't exist in Table2, if then insert.
If the unique constraint on TABLE2 is a composite key then run this:
INSERT INTO TABLE2 (ID, NAME)
SELECT A.ID, A.NAME
FROM TABLE1 A
WHERE NOT EXISTS (SELECT NULL FROM TABLE2 B WHERE A.ID=B.ID AND A.NAME=B.NAME);
If there are two unique constraints; one on the id, and the other on the name then run this instead:
INSERT INTO TABLE2 (ID, NAME)
SELECT A.ID, A.NAME
FROM TABLE1 A
WHERE NOT EXISTS (SELECT NULL FROM TABLE2 B WHERE A.ID=B.ID OR A.NAME=B.NAME);
ORACLE, in case you need to get values from 2 different tables.
below example,i use an increment case.
INSERT INTO TABLE1
(INDEX, REMARKS, NAME, AGE)
(SELECT (SELECT colescs(MAX(INDEX),0) FROM TABLE1)+1,
'any remarks',
t2.NAME, t2,age from TABLE2 t2 where t2.name = 'apple')
explanation
match below numbers (1)-(1), (2)-(2) ...
INSERT INTO TABLE1
(INDEX, //index increment (1)
REMARKS, //hard code (2)
NAME, //from table2 (3)
AGE) //from table2 (4)
(SELECT // this part is to get values from another table
(SELECT colescs(MAX(INDEX),0) FROM TABLE1)+1, //increment (1)
'any remarks', //hard code value (2)
t2.NAME, //from table2 (3)
t2,age //from table2 (4)
from TABLE2 t2 where t2.name = 'apple') //condition for table2

Oracle Merge: Update single record in base table using multiple records from source table

I have a merge query as follows:
merge into table1
using table2
on (table1.column1 = table2.column1)
when mateched then
update
set column2 = table2.column2;
Now it is giving me error like :unable to get a stable set of rows in the source tables
Now the issue is the source table, table2, is having multiple records for same column1 value and table1 is having only one record per column1 value.And I need all the table2 to update table1. can you pls help here?
" the issue is the source tabletable2, is having multiple records for same column1 value "
You need to ensure your sub-query returns only one row per value of column1. Only you know what exact business rule you need to apply, but it could be something like this:
merge into table1
using ( select column1, max(column2) as column2
from table2
group by column1 ) t2
on (table1.column1 = t2.column1)
when matched then
update
set column2 = t2.column2;
"I need all records from table2 to update table1. The reason is that I have a trigger on table1 which captures all transactions(inserts/updates) and loads to another history table. "
You can't use MERGE. In fact you're probably going to have to go procedural:
begin
for t2rec in (select column1, column2
from table2
order by column1, column2 )
loop
update table1
set column2 = t2rec.column2
where column1 = t2rec.column1;
end loop;
end;
You'll need to order the loop statement to ensure the end state of table1 is right.
Alternatively you could disable the journaling trigger and do this:
insert into table1_journal
select table1.column1
, table2.column2
from table1
join table2
on table1.column1 = table2.column1
/
Then do the MERGE or a single row update.

Oracle 20 million update based on join

I have a need to do the following
UPDATE TABLE2 t2
SET t2.product_id = (select t1.product_id from
table1 t1 where t1.matching_id = t2.matching_id)
Except that TABLE2 has 27 million records. The product_id is a newly added column and hence populating data to it.
I could use a cursor , break down my record set in TABLE2 to a reasonably smaller number, But with 27 million records, I am not sure whats the best way.
Pl suggest, even if it means exporting my data to excel.
Update - THe matching columns are indexed too.
The only thing I could do different is replace the update for a CREATE TABLE AS
CREATE TABLE table2_new AS
SELECT t2.* (less product_id), t1.product_id
FROM table1 t1
JOIN table2 t2
ON t1.matching_id = t2.matching_id
But later you will have to add the CONSTRAINTS manually, delete table2 and replace for table2_new
update (select t1.product_id as old_product_id, t2.product_id as new_product_id
from table1 t1
join table2 t2 on (t1.matching_id = t2.matching_id)) t
set t.new_product_id = t.old_product_id

Oracle join query

I have two tables
Table A has columns id|name|age.
Table B has columns id|name|age.
Sample Records from table A
1|xavi |23
2|christine|24
3|faisal |25
5|jude |27
Sample Records from table B
1|xavi |23
2|christine|22
3|faisal |23
4|ram |25
If id values from table A matches in table B than take records from table A only.
Also take records which are present in table A only
Also take records which are present in table B only
So my result should be
1|xavi |23
2|christine|24
3|faisal |25
4|ram |25
5|jude |27
You can simply use union operator to get unique values from both tables. Operator UNION will remove repeated values.
SELECT * FROM tableA AS t1
UNION
SELECT * FROM tableB AS t2
You have a precedence problem here. Take all the records from table A and then the extra records from table B:
select *
from A
union all
select *
from B
where B.id not in (select A.id from A);
You can also express this with a full outer join (assuming id is not duplicated in either table):
select coalesce(A.id, B.id) as id,
coalesce(A.name, B.name) as name,
coalesce(A.age, B.age) as age
from A full outer join
B
on A.id = B.id;
In this case, the coalesce() gives priority to the values in A.
select distinct * FROM
(
select ID, NAME, AGE from TableA
UNION ALL
select ID, NAME, AGE from TableB
) TableAB
Some things to consider --> Unless you're updating specific tables and the records are the same, it will not matter which table you're viewing the records from (because they're the same...).
If you want to see which table the records are deriving from, let me know and i'll show you how to do that as well... but the query is more complex and i don't really think it's required for the purpose described above. let me know if this helps... thanks, Brian
If the tables has relation you need:
Select DISTINCT *
from tableA a
Inner Join tableB b
On a.id = b.id
If not:
You have to use UNION and after using DISTINCT.
DISTINCT will not permit repeat rows.

Resources