Oracle 20 million update based on join - oracle

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

Related

compare two tables and delete rows from one table if there are similar coumn values in two tables hive

Table description are in the link
Table 1 and Table 2 has rows with A and D .I need these two removed from Table 2 .
Please check the link below for descriptive detail . Thank you .
You may do an INSERT OVERWRITE using a LEFT JOIN select query.
INSERT overwrite TABLE table2
SELECT t2.*
from table2 t2
LEFT JOIN table1 t1
on (t1.x = t2.p) --use appropriate common column name
WHERE t1.x is NULL; --where there's no common element in t2

Oracle join clause where varchar2(4 byte) causing issue

Title was tough to choose my wording.
I have 2 tables I want to join together via a lg_code. Both columns are VARCHAR2(4 byte). I am running into an issue where table1 lg_code = 0003 and table2 lg_code = 3. The three 0's are causing an issue with the join and not returning all the data needed. How would I go about writing the join clause to fix this issue?
Code:
select * from table1 t1 JOIN table2 t2 ON t1.LG_CODE = t2.LG_CODE
I would suggest to convert the value of the columnlg_code to number first then make the join:
SELECT * FROM table1 t1
JOIN table2 t2 ON to_number(t1.LG_CODE) = to_number(t2.LG_CODE)
you can also use ltrim() on them:
SELECT * FROM table1 t1
JOIN table2 t2 ON LTRIM(t1.LG_CODE, '0') = LTRIM(t2.LG_CODE, '0');
but in newer versions of oracle SQL*PLUS it trims automatically.

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.

Counting rows by a condition in another table

Need to count the number of rows in one table which connect to a second table by (name.sample) where in the second table the (name.sample) was created before (or after) a certain date.
select count(*) from table1 t1
inner join table2 t2 on t1.my_foreign_key_column = t2.my_primary_key_column
where t2.creation_date >= 'my_date_literal'

Does Oracle re-hash the driving table for each join on the same table columns?

Say you've got the following query on 9i:
SELECT /*+ USE_HASH(t2 t3) */
* FROM
table1 t1 -- this has lots of rows
LEFT JOIN table2 t2 ON t1.col1 = t2.col1
AND t1.col2 = t2.col2
LEFT JOIN table3 t3 ON t1.col1 = t3.col1
AND t1.col2 = t3.col2
Due to 9i not having RIGHT OUTER HASH JOIN, it needs to hash table1 for both joins. Does it re-hash table1 between joining t2 and t3 (even though it's using the same join columns), or does it keep the same hash information for both joins?
It would need to rehash since the second hash would be table3 against the join of table1/table2 rather than against table1. Or vice versa.
For example, say TABLE1 had 100 rows, table2 had 50 and table3 had 10.
Joining table1 to table2 may give 500 rows. It then joins that result set to table3 to give (perhaps) 700 rows.
It won't do a join of table1 to table2, then a join of table1 to table3, then a join of those two intermediate results.
Look at the plan, it'll tell you the answer.
An example might be something like (I've just made this up):
SELECT
HASH JOIN
HASH JOIN
TABLE FULL SCAN table1
TABLE FULL SCAN table2
TABLE FULL SCAN table3
This sample plan involves a scan through table1, hashing its contents as it goes; scans through table2, hashes the results of the join into a second hash, then finally scans table3.
There are other plans it could choose from.
If table1 is the biggest table, and the optimizer knows this (due to stats), it probably won't drive from it though.

Resources