oracle insert into column using subquery - oracle

I want to insert data into a column in the table.
Table a
ID col1 col2
1 A null
2 B null
Table b
ID col1
1 C
2 D
Expected results:
Table A
ID col1 col2
1 A C
2 B D
I tried this:
insert into tableA (col2)
select b.col1
from tableB b , tableA a
where b.id = a.id
and I received
0 row inserted.
How do I insert the col1 in B into col2 in A for the matching 'id' columns?
Thank you.

You must use Merge statement when inserting based on joins.
Also in table tableA col2 already exist but you want to insert a value on join then you must update that column.
merge into tablea a
using tableb b
on (b.id = a.id)
when matched
then
update set a.col2 = b.col1;

What you want to do shouldn't require a subquery. I'm not a huge fan of the table a, table b notation, try this:
update a
set col2 = b.col1
from tableB b
join tableA a
on a.id = b.id

Related

Multiple joins with count on a hive table

So I have 4 different tables and I want to put them in one table with one of the columns from the tables and the # of times a particular value appears in that column. All the columns are strings.
For example:
table A
col1
20190204
20190204
20190204
20190205
20190205
20190205
Table B
col1
20200204
20200204
20200204
20200204
20200205
20200205
20200205
TableC
col1
20210204
20210204
20210204
20210204
20210205
20210205
20210205
TableD
col1
20220204
20220204
20220204
20220204
20220205
20220205
20220205
TableE -- All the 4 tables will go into here
TableE is empty and needs to be populated with the dates from the other tables and the number of times they occur in those tables. For example:
col1(tablea) col2 col3(tbaleb) col4 col5(tablec) col6
20190204 4 20200204 4 20210204 4
20190205 3 20200205 3 20210205 3
col7(tabled) col8
20220205 3
20220205 4
etc...
I am new to hue, so I tried something like this:
insert overwrite into tablee (
tablee.tablea.date, tablee.tablea.datecount,
tablee.tablebdate, tablee.tableb.datecount,
tablee.tablecdate, tablee.tablec.datecount,
tablee.tableddate, tablee.tablea.datedcount,
select tablea.date, count(tablea.date),
tableb.date, count(tableb.date),
tablec.date, count(tablec.date),
tabled.date, count(tabled.date)
)
from tablea, tableb, tablec, tabled
left join tablee on (tablea.date=tablee.date)
left join tablee on (tableb.date=tablee.date)
left join tablee on (tablec.date=tablee.date)
left join tablee on (tabled.date=tablee.date);
But I am not able to get it to work correctly. Does anyone have any tips?
Please check if below query gives your desired result set.
select * from (select col1,count(*) from tablea group by 1)a
full outer join
(select col1,count(*) from tableb group by 1)b on a.col1=b.col1
full outer join
(select col1,count(*) from tablec group by 1)c on b.col1=c.col1
full outer join
(select col1,count(*) from tabled group by 1)d on c.col1=d.col1;
First all the grouped data from each table is calculated and then we doing full outer join to include all values of col1 from each table to get result set. Finally if the result set is what the desired one we can convert select statement to insert into/overwrite statement.

Concat Results of 2 Select Queries into 1 Column (oracle)

Im trying to insert a record into my table. But there is 1 column in which I want to get concatenated results of 2 select statements. Like the 2 statements will fetch their records and concatenate to form 1 value so that it can be inserted into the column.
insert into ABC (Name,City,Age)
Values ('John',(
(Select City from TableA where ID=1)concat(Select City from TableA where ID=2)),'22')
Or it can be comma separated but I am not getting what to use here.
Try this one:
INSERT INTO ABC (Name, City, Age)
VALUES ('John',
(
(SELECT City FROM TableA WHERE ID = 1) ||
(SELECT City FROM TableA WHERE ID = 2)
),
'22');
But ensure ... WHERE ID = 1 and ....WHERE ID = 2 return one row.
Using a cross join to select from the two tables produces a nice clear statement:
insert into ABC (Name,City,Age)
select 'John', concat(t1.city, t2.city), 22
from TableA t1
cross join TableA t2
where t1.ID = 1
and t2.ID = 2
/
Use CONCAT() or CONCAT_WS() functions for this (reference)
insert into ABC (Name,City,Age) Values (
'John',
CONCAT_WS(' ', (Select City from TableA where ID=1), (Select City from TableA where ID=2)),
'22'
)

INNER JOIN on multiple columns with multiple matches

How to find what rows got exact one match and what rows got more than one match in a INNER JOIN ?
SELECT A.Col1, B.Col2 FROM A INNER JOIN B
ON A.Col3 = B.Col3 AND A.Col4 = B.Col4;
As we know INNER JOIN returns rows with minimum one match, so to again reiterate my qustion, how to find which rows matched once and which rows got more than one match.
Regards,
Sachin
You could use a window function to count how many records are coming from B:
SELECT A.Col1, B.Col2, Count(*) OVER (PARTITION BY b.col3, b.col4) as bcount
FROM A
INNER JOIN B
ON A.Col3 = B.Col3 AND A.Col4 = B.Col4;
With the help of JNevill's inputs, here is a working example of what I was looking for. I want to thank JNevill once again.
create table A (col1 number, col3 number, col4 number, col5 number, col6 number);
create table B (col2 number, col3 number, col4 number, col5 number, col6 number);
insert into A values (1,2,3, 4, 5);
insert into A values (2,3,4,5,6);
insert into B values (3,4,5,6,7);
insert into B values (4,2,3,4,5);
insert into B values (5,2,3,8,9);
insert into B values (6,3,4,5,6);
insert into B values (7,3,4,5,6);
SELECT Col1 FROM(
SELECT A.Col1,B.Col2, A.Col3, A.Col4, A.Col5 ,A.Col6, Count(*) OVER (PARTITION BY B.col3, B.col4, B.col5, B.col6) as bcount
FROM A
INNER JOIN B
ON A.Col3 = B.Col3 AND A.Col4 = B.Col4 AND A.Col5 = B.Col5 AND A.Col6 = B.Col6) WHERE BCOUNT = 1;
So, I was looking for a column from table A which has exact one match for all the joining columns in table B.
Regards.

ORACLE Update with MINUS result

In Oracle 10g, I want to update the records of the resulting minus query below:
(
SELECT A,B,C FROM Table1
MINUS
SELECT A,B,C FROM Table2
)
The column that is to be updated is not part of the minus query as its not present in both tables so the below code is not an option
UPDATE
(
SELECT A,B,C FROM Table1
MINUS
SELECT A,B,C FROM Table2
)
SET TABLE1.D = 'TEST'
How about:
update table1
set d = 'TEST'
where (a,b,c) not in(select a,b,c from table2);
Edit:
The performance of minus generally suck, due to the sort operation.
If any of {a,b,c} are nullable, try the following instead:
update table1 t1
set t1.d = 'TEST'
where not exists(
select 'x'
from table2 t2
where t2.a = t1.a
and t2.b = t1.b
and t2.c = t1.c
);
In response to your comment about wanting to use the minus clause:
update Table1
set d = 'TEST'
where (a,b,c) in (select a,b,c from Table1 minus select a,b,c from Table2);

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

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.

Resources