append column from one table to another table in Oracle - sql

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

Related

How to Select all columns of a table except one

My code looks like:
CREATE TABLE tableC AS
(SELECT tableA.*,
ST_Intersection (B.geom, A.geom) as geom2 -- generate geom
FROM tableB, tableA
JOIN tableB
ON ST_Intersects (A.geom, b.geom)
WHERE test.id = 2);
Now It is working but I have two columns geom and geom2!
Inside geom column I will have the new geometry based on the intersection. So how can I select tableA except the geom column?
Create the table with all the columns and after that drop the geom column and rename the new one:
CREATE TABLE tableC AS
SELECT
tableA.*,
ST_Intersection (B.geom, A.geom) as geom2 -- generate geom
FROM
tableA inner JOIN tableB ON ST_Intersects (A.geom, b.geom)
WHERE test.id = 2
;
alter table tableC drop column geom;
alter table tableC rename column geom2 to geom;
The only way you would be able to do this would be to generate a dynamic SQL statement based on the columns within the table that excludes those you don't want. Obviously this will be a lot more effort than simply adding in all the column names.
There are also a lot of very good reasons to never include a select * in a production environment, given how picky SQL often is on the number and format of columns that are returned. By using select * you open yourself up to a changing query result in the future that could potentially break things.
If you have a LOT of columns and you simply don't want to manually type them all out, run the query below for your table and then format the result so you can copy/paste into your script:
SELECT *
FROM information_schema.columns
WHERE table_schema = 'your_schema'
AND table_name = 'your_table'

How to print all columns when columns are dynamic and one common column is present?

Lets say i have 2 table A,B .In both the tables (id) is the common column ,and rest columns dynamic.so write a query to print id of "A" and rest all columns .
A(id,name,city),B(id,phone,phone_num). Here I only know "id" column ,rest columns(name,city,phone) are coming dynamically,So i can not use A.name,A.city,B.phone etc .In
select * from A FULL OUTER JOIN B ON A.id = B.id;
is printing id column twice.
If you want to display the id column only once, use the using clause for the join :
SELECT *
FROM tableA a
JOIN tableB b using (id)
The using clause as the effect that the join column(s) are only included once with select *.
If I'm not wrong, you want to display all the column of both the tables and the common column i.e id should come only once.If that's the case use the below query and replace the column name with the column names you want to display.
SELECT a.id,a.column1,a.column2,b.column1,b.column2
FROM tableA a
INNER JOIN tableB b ON a.id=b.id
Demo
create table my_table_1 (id int,c1 int,c2 int,c3 int);
create table my_table_2 (id int,c4 int,c5 int);
select array_to_string(array_agg (table_name || '.' || column_name::text),',')
from information_schema.columns
where table_name in ('my_table_1','my_table_2')
and not (table_name,column_name) = ('my_table_2','id')
my_table_1.id,my_table_1.c1,my_table_1.c2,my_table_1.c3,my_table_2.c4,my_table_2.c5

Trying to Merge data from one table to another

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)

Singe SQL Query to retrieve fields from 2 different table.

Trying to explain my Question:
Say, Table A contains ID,Number,Location.
Table B contains Option 1,Option 2.
I want to write a single query that would select ID, Number & Option 1 from the Table A and Table B.
(At present I am doing something like:
SELECT ID FROM [A]
SELECT Option 1 FROM [B]
)
You do this:
SELECT A.ID, A.Number, B.Option1
FROM TableA as A, TableB as B
WHERE A.id = B.id;
This Part sets an alias for the table so that you don't have type in the full table name all the time:
TableA as A
TableB as B
This part is the relationship between table A and B.
WHERE A.id = B.id;
Consider reading SQL table relationships http://net.tutsplus.com/tutorials/databases/sql-for-beginners-part-3-database-relationships/

Update query to get new records without a unique key?

I have a table of accounting transactions and I am trying to copy them into a new table. I have the copy worked out, but I need to update the copy with any new transactions from my source table. The problem I have is that the source data is coming from a report that links many different sources to create these transactions and doesn't have a unique key.
If I had a unique key, I would create an update query and do a left join from the source table to the copied table and anytime the key is null in the copied table, update those fields.
Since I don't have a unique key, I don't know how to accomplish this. Any ideas?
-----Edit due to Answers-----
SourceTable
Field1 Field2 Field3
CopiedTable
Field1 Field2 Field3
So to update CopiedTable with new records I would do this??
UPDATE CopiedTable SET
CopiedTable.Field1 = SourceTable.Field1,
CopiedTable.Field2 = SourceTable.Field2,
CopiedTable.Field3 = SourceTable.Field3
WHERE (SourceTable.Field1 <> CopiedTable.Field1 AND
SourceTable.Field2 <> CopiedTable.Field2 AND
SourceTable.Field3 <> CopiedTable.Field3)
It is difficult to answer the question without seeing the source tables, the destination table and the query.
Use a compound key consisting of all the unique key fields of the different tables.
EDIT:
Every table must have a primary key. This is a basic design rule for databases. Let us assume that you have two source tables A and B
Table A
-------
A_ID, DataField1, DataField2
Table B (lined to Table A through A_ID)
-------
B_ID, A_ID, DataField3, DataField4
Now you can create table C like this
SELECT
CLng(A.A_ID) AS A_ID, CLng(B.B_ID) AS B_ID,
A.DataField1, A.DataField2, B.DataField3, B.DataField4
INTO
C
FROM
A INNER JOIN B ON A.A_ID = B.A_ID;
I would make A_ID and B_ID a primary key in C.
If A_ID and B_ID are AutoNumbers we need to do a trick with CLng in order to create regular number fields in C.
If later we want to refill C with fresh data from A and B, we can do
DELETE * FROM C;
INSERT INTO C
(A_ID, B_ID, DataField1, DataField2, DataField3, DataField4)
SELECT
A.A_ID, B.B_ID, A.DataField1, A.DataField2, B.DataField3, B.DataField4
FROM
A INNER JOIN B ON A.A_ID = B.A_ID;
If we want to update only changed records, we need to link the source with the copy and, in addition, test if we have changes in the WHERE clause
UPDATE
C
INNER JOIN (SELECT
A.A_ID, B.B_ID,
A.DataField1, A.DataField2, B.DataField3, B.DataField4
FROM
A INNER JOIN B ON A.A_ID = B.A_ID) AS Src
ON C.B_ID = Src.B_ID AND C.A_ID = Src.A_ID
SET
C.DataField1 = Src.DataField1,
C.DataField2 = Src.DataField2,
C.DataField3 = Src.DataField3,
C.DataField4 = Src.DataField4
WHERE
C.DataField1<>Src.DataField1 OR
C.DataField2<>Src.DataField2 OR
C.DataField3<>Src.DataField3 OR
C.DataField4<>Src.DataField4;
The sub-select Src could be another stored query.