Update large amount of rows from other table - sql

Let's say I have Table1 (Id, Row1, Row2) and Table2 (Id, Row1, Row2) with same schema.
In table1 I have data with the same id than in table2 and I want to update Row1 and Row2 for each corresponding Id. But I have a lot of data (around 10 000 000 rows) and it's very slow with a loop.
Is it possible to update all rows faster?
Note: I can't truncate and bulk insert because in table2 I can have data that is not in table1.

Sure. Just join the two tables together, and run an UPDATE over the results of the JOIN, eg:
with q as
(
select t1.id, t1.Col1, t1.Col2, t1.Col3,
t2.Col1 Col1_new, t2.Col2 Col2_new t2.Col3 Col3_new
from Table1 t1
join Table2 t2
on t1.id = t2.id
)
--select * from q
update q set Col1 = Col1_new, Col2 = Col2_new, Col3 = Col3_new

Related

How to update multiple columns in the oracle SQL on ATP fusion DB

I am trying to use the below query, its everytime saying cannot insert null for the second column.
UPDATE TABLE1
SET (COL1,COL2,COL3) = (SELECT COL1,COL2,COL3
FROM TABLE2
WHERE t1.id = t2.id);
Try this:
UPDATE TABLE1 SET (COL1,COL2,COL3) =
(SELECT COL1,NVL(COL2,0),COL3 FROM TABLE1 T1, TABLE2 T2 where t1.id = t2.id)
WHERE <YOUR WHERE CONDITION>
I would use a MERGE:
MERGE INTO TABLE1 t1
USING (SELECT id, COL1,COL2,COL3
FROM TABLE2) t2
ON (t1.id = t2.id)
WHEN MATCHED THEN UPDATE SET t1.COL1 = t2.COL1
, t1.COL2 = t2.COL2
, t1.COL3 = t2.COL3;
There are rows in table1 where not corresponding row exists in table2 thus the sub-query returns nothing which means the UPDATE statement will take that as null for all three columns.
You have to add a WHERE clause that only updates rows in table1 that do have a matching row in table2
UPDATE TABLE1
SET (COL1,COL2,COL3) = (SELECT COL1,COL2,COL3
FROM TABLE2 t2
WHERE table1.id = t2.id)
where exist (select *
from table2 t2
where table1.id = t2.id);

inserting into a table records from another table with a condition

Let's say I have two tables t1 and t2.
t1 has two integer cols col1 (primary) and col2
t2 has two cols a foreign key of t1.col1 and t2.col2
I want to do the following
Retrieve only the records where t1.col2 is unique OR if t1.col2 is duplicate only those if t2.col2 is not null.
Insert the above records into another summary table, let's say t3
This is what I tried:
insert into t3 (col1,col2)
select col1, col2
from t1
where t.col1 in (select A.col1 from t1 as A
group by 1
having count(*) > 1
union
select col1, col2
from t1, t2
where t.col1 in (select A.col1 from t1 as A
group by 1
having count(*) > 1
and t2.col2 is not null;
While the 'union qry' works on its own, the insert is not happening.
Any ideas or any other efficient way to achieve this please
You can select the records you want using:
select t1.*
from (select t1.*, count(*) over (partition by col2) as cnt
from t1
) t1
where cnt = 1 or
exists (select 1 from t2.col1 = t1.col1 and t2.col2 is null);
The rest is just an insert.

query 2 tables and get all records from table A and include one field from 2nd

table 1
col1 col 2
A aaa
B bbb
C ccc
table 2
col1 col 2 col3
A aaa xx
B bbb yy
C ccc zz
D ddd hh
E eee mm
How to write a query where i get all of table1 data and only col3 to existing records of Table 1. table1 has only 50 records and Table2 has 100k. But i need only all 50 records of Table 1 and only col3 added to the record by joining
table1. col1 = table2.col1
Based on the description, I would suggest this query:
SELECT
t1.col1,
t2.col2,
t2.col3
FROM
table1 AS t1
INNER JOIN
table2 AS t2 ON (t2.col1 = t1.col1 AND t2.col2 = t1.col2)
The SELECT clause determines what columns will appear in the result set. Your description gives us some assistance here.
For a join, choosing the correct join type is important to what query you are making. Your description is helpful for this:
How to write a query where I get all of table1 data and only col3 to existing records of Table 1.
“get all of table1” implies that the result set should include all columns from that table.
SELECT table1.col1, table1.col2 […]
“get all of table1” implies that table1 is the primary source in the FROM clause.
[…] FROM table1 […]
“only col3 [from table2]” implies that the result set should also include that column.
SELECT […] table2.col3
“only […] to existing records of table1” implies that the join type is INNER JOIN.
FROM table1
INNER JOIN table2 […]
“only col3 to existing records of table1” implies that is the join condition.
FROM table1
INNER JOIN table2 ON table2.[…] = table1.[…]
But you don't specify exactly what condition tells us what records are equivalent between the tables. Shall we assume that the condition is for all columns named the same to have the same value?
FROM table1
INNER JOIN table2 ON (table2.col1 = table1.col1 AND table2.col2 = table1.col2)
We will be using the tables several times, so it's good practice to set concise AS aliases in the FROM clause.
You want INNER JOIN :
SELECT t1.col1, t1.col2, t2.col3
FROM table1 t1 INNER JOIN
table2 t2
ON t2.col1 = t1.col1;
Try left join:
SELECT t1.col1, t1.col2, t2.col3
FROM table1 t1 LEFT JOIN
table2 t2
ON t1.col1 = t2.col1 AND t1.col2 = t2.col2;

Delete Rows in a table Based on column value in third table

I have three tables Table1, Table2 and Table3 and the following query which deletes rows in Table1
delete from Table1
where EXISTS
(select (1) from Table2
where Table1.col1=Table2.col1
AND Table1.col2=Table2.col2
AND Table1.col3=(select **Table3.col3 from Table3** inner join Table2 on Table3.col1=Table2.col1)
Is this query correct? If not, how to use a third table inside the where condition?
Edit : Also, please explain how to rewrite the query if we want to delete the rows from table2 which itself is joined with table3?
Here's one way to do it:
delete from table1
where (col1, col2, col3) in (
select t1.col1, t1.col2, t1.col3
from table1 t1
join table2 t2 on t1.col1 = t2.col1 and t1.col2 = t2.col2
join table3 t3 on t1.col3 = t3.col3 and t2.col1 = t3.col1
);
SQL Fiddle Demo
Or using EXISTS might be faster:
delete table1
where exists (
select *
from table2
join table3 on table2.col1 = table3.col1
where table1.col3 = table3.col3 and
table1.col1 = table2.col1 and
table1.col2 = table2.col2);

compare two table values

I have 2 tables table A and table B. In table B we have to check if all the column entered is exactly as in table A, means if a row exists in table B then the same row will be there in table A too. also table A may have rows which are not in table B. if there is a row which is not in table A and is there in table B, an alert should be displayed showing which element is extra in table B.
Can we do this using join? if so what will be the sql code?
this is the best picture about joins i've ever seen :)
You probably want to have a look at the following article
SQL SERVER – Introduction to JOINs – Basic of JOINs
This should give you a very clear understanding of JOINs in Sql.
From there you should be able to find the solution.
As an example, you would have to look at something like
TABLE1
Col1
Col2
Col3
Col4
TABLE2
Col1
Col2
Col3
Col4
--all rows that match
SELECT *
FROM TABLE1 t1 INNER JOIN
TABLE2 t2 ON t1.Col1 = t2.Col1
AND t1.Col2 = t2.Col2
...
AND t1.Col3 = t2.Col3
--rows only in TABLE1
SELECT *
FROM TABLE1 t1 LEFT JOIN
TABLE2 t2 ON t1.Col1 = t2.Col1
AND t1.Col2 = t2.Col2
...
AND t1.Col3 = t2.Col3
WHERE t2.Col1 IS NULL
--rows only in TABLE2
SELECT *
FROM TABLE1 t2 LEFT JOIN
TABLE2 t1 ON t1.Col1 = t2.Col1
AND t1.Col2 = t2.Col2
...
AND t1.Col3 = t2.Col3
WHERE t1.Col1 IS NULL
If you want to compare based on single column, then you can do something like this:
SELECT ID FROM B LEFT JOIN A ON B.ID = A.ID WHERE A.ID IS NULL;
The above query will give you the list of records that are not present in A but in B.
Instead if you want to compare the entire row, you can use the following approach:
SELECT COUNT(*) FROM B;
SELECT COUNT(*) FROM A;
SELECT COUNT(*) FROM (
SELECT * FROM B UNION SELECT * FROM A
)
If all the queries returns the same count then you can assume that both the tables are exactly equal.