Aggregate columns but distinct terms should be inserted - oracle

I have two table and I want to merge them
TERMS_TABLE
ID | TERMS
309 | 'hardware'
309 | 'software'
309 | 'computer'
TFIDF_TABLE
ID | TERMS
309 |'computer,phone,mp3....'
Now I want to add TERMS column of TERMS_TABLE to terms column of TFIDF_TABLE but If TFIDF_TABLE already contains TERMS of TERMS_TABLE then I should not insert this term to the NEW_TFIDF_TABLE , like that
result should be:
NEW_TFIDF_TABLE
ID | TERMS
309 |'computer,phone,mp3....,hardware,software'
How can I do that ?

If you use Oracle 11 you can try this:
select t3.id, t3.terms||','||t4.terms terms from
(
select t1.id, listagg(t1.terms,',') within group (order by t1.terms) terms
from terms_table t1 join tfidf_table t2 on t1.id=t2.id
where instr(t2.terms,t1.terms)=0
group by t1.id )
t3 right outer join tfidf_table t4 on t3.id=t4.id
On Oracle 10 you could try
select t3.id, t3.terms||','||t4.terms terms from
(
select t1.id, wm_concat(t1.terms) terms
from terms_table t1 join tfidf_table t2 on t1.id=t2.id
where instr(t2.terms,t1.terms)=0
group by t1.id )
t3 right outer join tfidf_table t4 on t3.id=t4.id

Related

Oracle - Joining a basic join query with a count/group by having query

I have two queries. One basic join query and one query that uses a count/having/group by. The query that uses count is using a table also used in the basic join so I figured I could do either add another join or some sort of sub query.
What I want to do is add one or more columns from another table to query 2.
Query 1
SELECT t1.col1,
, t2.col12
FROM Table1
inner join Table2 t2
on t1.ID_NO = t2.ID_NO
Query 2
SELECT t2.col1||t2.col2, count(distinct t2.col3) Totals
FROM Table2 t2 having count(distinct t2.col3) >=15 GROUP BY t2.col1, t2.col2
Name
Account
Totals
t1.col1
t2.col1 & t2.col2
count(distinct t2.col3)
You have not described what output you are expecting from your query but there are many routes you could take to join the tables:
Join to a sub-query:
SELECT t1.col1,
t2.col1 || t2.col2 AS col12,
t2.max_id_no,
t2.totals
FROM Table1 t1
INNER JOIN (
SELECT col1,
col2,
MAX(id_no) AS max_id_no,
COUNT(DISTINCT col3) AS Totals
FROM Table2
GROUP BY col1, col2
HAVING COUNT(DISTINCT col3) >=15
) t2
ON t1.id_no = t2.max_id_no
Or, join and then group:
SELECT t2.col1 || t2.col2 AS col12,
MAX(t1.col1) AS max_t1_col1,
COUNT(DISTINCT t2.col3) AS Totals
FROM Table1 t1
INNER JOIN Table2 t2
ON (t1.ID_NO = t2.ID_NO)
GROUP BY t2.col1, t2.col2
HAVING COUNT(DISTINCT t2.col3) >=15

Hive - create table by select columns from different tables

Here are my hive tables:
table1:
|a |b |c |
----------
|a1|b1|c1|
|a2|b2|c2|
|a3|b3|c3|
|a4|b4|c4|
|a5|b5|c5|
table2:
|x |y |z |
----------
|x1|y1|z1|
|x2|y2|z2|
|x3|y3|z3|
|x4|y4|z4|
|x5|y5|z5|
Desired output:
|a |b |x |y |
-------------
|a1|b1|x1|y1|
|a2|b2|x2|y2|
|a3|b3|x3|y3|
|a4|b4|x4|y4|
|a5|b5|x5|y5|
is it really possible in hive? Any help would be appreciated, Thank you!
You seem to want to "line up" the rows of both tables. Assuming that column a can be used to order the record in table1 (resp column x in table2), you can use row_number() as follows:
select t1.a, t1.b, t2.x, t2.y
from (select t1.*, row_number() over(order by a) rn from table1 t1) t1
inner join (select t2.*, row_number() over(order by x) rn from table2 t2) t2
on t1.rn = t2.rn
If the tables may have a different number of rows, and you want to retain "additional" rows, you can just change the inner join to a full join.

Merge table data

Table1 Table2 Table3 Table4
Sl Name City index len bre col tax income price dicount org
1 ABC XYZ 1 10 12 1 23 40 1 10 XYZ
2 DEF asd 2 12 14 2 24 42 2 6 asd
3 ghi jkl 3 78 89 3 0 gah
These entries correspond to respective tables. I want to fetch data from all 4 tables irrespective of whether values are present in Table2 or not. Any null value in Table2 should not hamper the output.
select tab1.Name,
tab2.len,
tab3.tax,
tab4.org
From Table1 tab1,
Table2 tab2,
Table3 tab3,
Table4 tab4
where tab1.sl=tab2.index(+)
AND tab2.index(+)=tab3.col
AND tab3.col=tab4.price;
This query only returns results for those Sl for which there is entry in table 2. How can I resolve this?
To use a proper ANSI left join:
select tab1.Name,
tab2.len,
tab3.tax,
tab4.org
From Table1 tab1
inner join Table3 tab3 on tab1.sl.tab3.col
inner join Table4 tab4 on tab3.col=tab4.price
left join Table2 tab2 on tab1.sl=tab2.index;
This makes your code much more readable.
Try following ---
select tab1.Name,
tab2.len,
tab3.tax,
tab4.org
From
Table1 tab1 left join Table2 tab2
on tab1.sl=tab2.index(+) join Table3 tab3
on tab2.index(+)=tab3.col join Table4 tab4
on tab3.col=tab4.price;
Look, you should move from the 1990s into the early 2000s, by rewriting your query without the 'orrible omega-join (+) syntax.
Converting omega to join, your query comes out like this.
SELECT tab1.Name,
tab2.len,
tab3.tax,
tab4.org
FROM Table1 tab1,
left join Table2 tab2 ON tab1.sl=tab2.index
right join Table3 tab3 ON tab2.index=tab3.col
inner join Table4 tab4 ON tab3.col=tab4.price;
And, then the apparently chaotic combination of right, left, and inner join operations hints at the solution to your problem.
Change over to all left joins and your Table1 rows won't be suppressed when they don't match other tables.
SELECT tab1.Name,
tab2.len,
tab3.tax,
tab4.org
FROM Table1 tab1
LEFT JOIN Table2 tab2 ON tab1.sl=tab2.index
LEFT JOIN Table3 tab3 ON tab2.index=tab3.col
LEFT JOIN Table4 tab4 ON tab3.col=tab4.price;
Even if you must use the old omega join syntax, you should use it in a way which won't suppress rows from Table1
select tab1.Name,
tab2.len,
tab3.tax,
tab4.org
From Table1 tab1,
Table2 tab2,
Table3 tab3,
Table4 tab4
where tab1.sl=tab2.index(+)
AND tab2.index=tab3.col(+)
AND tab3.col=tab4.price(+);
The position of the (+) on the right means it's a left join, and vice versa.

Retrieve from Oracle db key value pair

I need to retrieve 3 values with different key from a key value pair table.
My database schema as follows. I need to reach to table3 from table1 by taking the E_SUBID and then joining the table2 with E_SUBID. Once table1 and table2 are joined I need take to take E_CID from table2 to join it with table2 E_CID to get the "Attr_Value" keeping E_CID as a criteria.
Table1
------------------------
|E_SUBID| B_LocationID |
|1 100 |
|2 101 |
|3 102 |
Table2
-----------------
|E_CID | E_SUBID|
|10 1 |
|11 2 |
|12 3 |
Table3
---------------------------------
|E_CID | Attr_name | Attr_Value |
|10 Product Samsung |
|10 Model Smartphone |
|10 usage daily |
|11 Product Apple |
|11 Model Ipad |
|11 usage everyday |
|12 Model smartwatch |
I have been successful to join table1,table2 and table3 but I cannot get the required output which as follows
OUTPUT
|Product | Model | Usage |
Samsung Smartphone daily
Apple Ipad everyday
null smartwatch null
The query which joins table1, table2 and table3 as follows
select distinct t3.Attr_value as Product
from table1 t1, table2 t2, table3 t3
where t1.E_SUBID = t2.E_SUBID and
t2.E_CID = t3.E_CID and
t3.Attr_name=?????
order by Product;
Thank you for your time.
In a case like this, you can join to table3 as often as you need to for each attribute name you wish to display:
select
p.attr_value product,
m.attr_value "model", -- Quotes to escape reserved word
u.attr_value usage
from table1 t1
join table2 t2 on t1.e_subid = t2.e_subid
left outer join table3 p on t2.e_cid = p.e_cid and p.attr_name = 'Product'
left outer join table3 m on t2.e_cid = m.e_cid and m.attr_name = 'Model'
left outer join table3 u on t2.e_cid = u.e_cid and u.attr_name = 'Usage'
order by 1;
Edit
Based on the comment, by making table3 optional (outer join) the query should return all rows and whether or not a Model or Usage or Product has been defined.
Try as below ... Basically you are trying to transpose the rows to column in table3.
Select Product, "Model", Usage
From
(
Select
t1.E_SUBID,
t2.E_CID,
Max(Case when T3.Attr_name = 'Product' Then T3.Attr_Value else null end) Product,
max(Case when T3.Attr_name = 'Model' Then T3.Attr_Value else null end) Model,
max(Case when T3.Attr_name = 'Usage' Then T3.Attr_Value else null end) Usage
From Table1 t1,
Table2 t2,
Table3 t3
Where
t1.E_SUBID = t2.E_SUBID
and t2.E_CID = t3.E_CID
group by t1.t1.E_SUBID,t2.E_CID
);

Update query Oracle

I have table TB1 which has the following cols:
ID | date
---------------------
1 | 12-JUL-10
2 | 12-JUL-10
3 | 12-JUL-10
4 | 12-JUL-10
.
.
.
10000 | 12-JUL-10
table2
ID | date
---------------------
1 | 12-JAN-09
2 | 12-JUL-09
3 | 12-JUL-09
4 | 12-JUL-08
.
.
.
5800 | 12-JUL-08
How to update the table2's date which has similar ID as table1.
Thanks :)
In general
UPDATE table2 t2
SET date_col = (SELECT t1.date_col
FROM table1 t1
WHERE t1.id = t2.id)
WHERE EXISTS (
SELECT 1
FROM table1 t1
WHERE t1.id = t2.id )
If you can be guaranteed that every ID in table2 exists in table1 (or if you want the date_col set to NULL if there is no match), you can eliminate the WHERE EXISTS. But generally you only want to do an update if there is a matching record.
Then there is also using an inline view for the update. This is slightly trickier to get right because I think it requires a primary key to exist on both sides of the join otherwise it fails with an error.
update (
select
t1.id as t1_id,
t1.value as t1_date,
t2.id as t2_id,
t2.value as t2_date
from
table1 t1
join table2 t2 on (t1.id = t2.id)
)
set t2_date = t1_date

Resources