Trying to Merge data from one table to another - sql

Trying to do a process where I have a table that is existing. This is table A
I have staging table which I have uploaded the data. This is table B.
Table A already contains data in there apart from some data which i need added from table B to Table A.
So Table B has a extra column which I need it to match with the data already existing in Table A.
So layout currently in Table A is:
Column 1 Column 2 Column 3
AB
ABC
Layout in Table B is:
Column 1 Column 2 Column 3
ABC Yellow Test1
AB Blue Test2
So I need these columns 2 and 3 moved to table A from Table B, so they match correctly with the data that is already in column 1.
Tried my best to explain and english is my 2nd language, so i apologise for any mistakes. Anyway know what best way to go with this, would it be a merge?
Thanks

Update TableA
Set TableA.Column2=B.Column2,
TableA.Column3=B.Column3
From TableA A
Inner Join TableB B ON B.Column1=A.Column1

Use Left Outer join to merge data
SELECT TableA.clomun1,
Tableb.column2.tableb.column3
FROM tableA
LEFT JOIN tableB
ON table1.column1 = table2.column1;

Following query is working fine in MySQL , try it out :
update TableA as a inner join TableB as b on a.Column1=b.Column1
set a.Column2 = b.Column2 , a.Column3=b.Column3
where a.Column1=b.Column1;
And for Oracle use this one :
update TableA
set TableA.Column2 =
(select TableB.Column2 from TableB where TableA.Column1=TableB.Column1),
TableA.Column3 =
(select TableB.Column3 from TableB where TableA.Column1=TableB.Column1);

MERGE INTO TableA
USING (SELECT Column1, COlumn2, Column3
FROM TableB) Q
ON (TableA.Column1=TableB.Column1)
WHEN MATCHED THEN UPDATE SET TableA.Column2=Q.Column2
, TableA.Column3=Q.Column3;
This works fine in Oracle. You can also insert records that are not in Table A adding
WHEN NOT MATCHED THEN INSERT (Column1, Column2, Column3)
VALUES (Q.Column1, Q.Column2, Q.Column3)

Related

Most Elegant Way to Populate Nulls from Reference Table

I have two tables like so:
Table 1:
Column 1 Column 2
A 1
B NULL
C 3
D 4
Table 2:
Column 1 Column 2
A 1
B 2
C 3
D 4
I receive the data in table 2 on a time delay, and what I need to do when I receive it is populate the null values in Table 1 with the data in table 2. Is there an elegant way to do this in Standard SQL without making temporary tables or using sub-queries?
Thanks!
Consider using a MERGE statement:
MERGE dataset.table1 AS t1
USING dataset.table2 AS t2
ON t1.column1 = t2.column1
WHEN MATCHED THEN
UPDATE SET t2.column2 = t1.column2
Take a look at the supported actions you can perform; if you want to insert new rows, you can do that using MERGE as well.
You can use the UPDATE statement from the DML (Data Manipulation Language) and update Table 1 in place.
It is not clear from your question how you receive data from Table 2, so I will assume that you have a temporary table called Table2. You will have to JOIN Table1 and Table2 in order to find which rows have NULL values, i.e Table1.Column2 IS NULL. Then update Column2 in those rows using the value in Table2. It should be something like this:
UPDATE Table1
SET Column2 = Table2.Column2
FROM
Table1 LEFT JOIN Table2 USING(Column1)
WHERE
Table1.Column2 IS NULL
Correct use of UPDATE statement would be
UPDATE `project.dataset.table1` a
SET Column_2 = b.Column_2
FROM `project.dataset.table2` b
WHERE a.Column_1 = b.Column_1
AND a.Column_2 IS NULL

append column from one table to another table in Oracle

Suppose i have one table named A with 3 columns(1 id column),and a table named B with two columns(1 id column).Table A and table B can join using column id.
Now I want to append one column from table B to table A by sql statements。so after executing,table A will have 4 columns.Both table A and table B have million rows,how can I do it efficiently?
Assuming this is a one-off consolidation of tables and you have a reason to do this rather than using a join (with or without a view):
alter table a add (col4 varchar2(10)); -- or whatever data type you actually need
merge into a
using b
on (b.id = a.id)
when matched then update set a.col4 = b.col4;
You could do a correlated updated:
update a set col4 = (
select col4 from b where b.id = a.id
);
but a merge is probably going to be quicker.
There are 2 steps to perform:
Changing the data model (ie. specifying the additional column for A)
Fill the column with suitable values.
These operations can be folded together if you can afford the resources to temporarily hold the data contained in A and B twice:
CREATE TABLE C AS (
SELECT a.id
, a.col2
, a.col3
, b.col2 AS col4
FROM A a
INNER JOIN B b ON ( b.id = a.id )
);
DROP TABLE A;
RENAME C TO A;
While the Alex Poole's answer is more efficient, the above solution works on oracle versions before 9i (esoteric) and on other rdbms ( syntax to rename the table might differ a bit, eg. alter table C rename to A in postgresql 9.x+)

create table to compare rows

In order to be able to use UTL_MATCH.JARO_WINKLER_SIMILARITY in oracle, i would need to have a table(temp table in my case) in following format
a ----------------abc
a ----------------bax
a ----------------tax
b ----------------abc
b ----------------bax
b ----------------tax
c ----------------abc
c ----------------bax
c ----------------tax
I have column in the LEFT coming from one table and the column in RIGHT from another table. My question is how to create table in such format?
I would highly appreciate your help.
If you want empty structure then:
create table test as
select table1.col1, table2.col2
from table1, table2
where 1=0
If you want table with data then:
create table test as
select distinct table1.col1, table2.col2
from table1, table2

How to loop through rows in two tables and create a new set based on the merged results in SQL

Here is my obstacle.
I have two tables. Table A contains more rows than Table B. I have to merge the results and if Table A does not contain a row from Table B then I insert it into the new set. If however, a row from Table A contains a row with the same primary key as Table B, the new set will take the row from Table B.
Would this best be done in a cursor or is there an easier way to do this? I ask because there are 20 million rows and while I am new to sql, i've heard cursors are expensive.
Your phrasing is a little vague. It seems that you want everything from TableB and then rows from TableA that have no matching primary key in B. The following query solves this problem:
select *
from tableB union all
select *
from tableA
where tableA.pk not in (select pk from tableB)
Yep, cursors are expensive.
There's a MERGE command in later versions of SQL that will do this in one shot, but it's sooo cumbersome. Better to do it in two pieces - first:
UPDATE A SET
field1 = B.field1
,field2 = B.field2
, etc
FROM A JOIN B on B.id = A.id
Then:
INSERT A SELECT * FROM B --enumerate fields if different
WHERE B.id not in (select id FROM A)
An OUTER JOIN should do what you need and be more efficient than a cursor.
Try this query
--first get the rows that match between TableA and TableB
INSERT INTO [new set]
SELECT TableB.* --or columns of your choice
FROM TableA LEFT JOIN TableB ON [matching key criteria]
WHERE TableB.[joining column/PK] IS NOT NULL
--then get the rows from TableA that don't have a match
INSERT INTO [new set]
SELECT TableA.* --you didn't say what was inserted if there was no matching row
FROM TableA LEFT JOIN TableB ON [matching key criteria]
WHERE TableB.[joining column/PK] IS NULL

Find SQL rows that are not shared between two tables with identical fields

I have two tables with identical fields that share many rows. I'd like to list all the rows in one table that cannot be matched in the other. Specifically, these two tables are two different versions of an experiment where the results differ slightly. An example is something like this:
|TableA|
--------
horse
cat
cow
table
|TableB|
--------
horse
cat
chair
I'd like to be able to see that TableA is missing chair from TableB and possibly in a different query that TableB is missing cow and table are missing from TableA.
My thought was to do some sort of outer join on all fields, then sort out the rows with nulls in them, but this seems heavy handed. Is this the way to go or is there are more elegant/efficient approach?
Using NOT IN:
SELECT a.column
FROM TABLE_A a
WHERE a.column NOT IN (SELECT b.column
FROM TABLE_B b)
Using NOT EXISTS:
This is a good one if you need to compare more than one column...
SELECT a.column
FROM TABLE_A a
WHERE NOT EXISTS(SELECT NULL
FROM TABLE_B b
WHERE b.column = a.column)
Using LEFT JOIN/IS NULL:
SELECT a.column
FROM TABLE_A a
LEFT JOIN TABLE_B b ON b.column = a.column
WHERE b.column IS NULL
Because of the table aliases, you could swap the table names without changing the rest of the query to see the opposite--rows from TABLE_B that aren't in TABLE_A.
be conscious when you are using IN clause for NULLABLE columns
If you want a single listing of all the rows that are in the left table and not the right one and all the rows that are in the right table and not the left table:
CREATE TABLE test1 (
idOne int identity primary key
,nameOne nvarchar (3)
)
CREATE TABLE test2 (
idTwo int identity primary key
,nameTwo nvarchar (3)
)
INSERT INTO test1 (nameOne) VALUES
('one'),
('two'),
('thr')
INSERT INTO test2 (nameTwo) VALUES
('one'),
('tre')
SELECT 'test2 row', idOne, nameOne, idTwo, nameTwo FROM test1 t1
RIGHT JOIN test2 t2 ON
t1.idOne = t2.idTwo and
t1.nameOne = t2.nameTwo
WHERE idONE is NULL
OR idTwo is NULL
UNION ALL
SELECT 'test1 row', idOne, nameOne, idTwo, nameTwo FROM test1 t1
LEFT JOIN test2 t2 ON
t1.idOne = t2.idTwo and
t1.nameOne = t2.nameTwo
WHERE idOne is NULL
OR idTwo is NULL