HiveQL UNION ALL - hadoop

I have table_A:
id var1 var2
1 a b
2 c d
Table_B:
id var1 var2
3 e f
4 g h
All I want is table, combined:
id var1 var2
1 a b
2 c d
3 e f
4 g h
This is my .hql:
CREATE TABLE combined AS
SELECT all.id, all.var1, all.var2
FROM (
SELECT a.id, a.var1, a.var2
FROM table_A a
UNION ALL
SELECT b.id, b.var1, b.var2
FROM table_B b
) all;
I'm coding straight from page 112 of Programming Hive by Edward Capriolo, et al.
The error I get, no matter what ostensibly reasonable variation of the above that I try, is
cannot recognize input near '.' 'id' ',' in select expression.
I have tried using AS between the table name and the alias, asterisks since I want everything from both tables. Same error. I've tried other things and gotten other errors... All I want to do is UNION two tables. (I've tried UNION instead of UNION ALL — same error).

Just replace all with another word. It seems to be a reserved keyword. E.g:
CREATE TABLE combined AS
SELECT unioned.id, unioned.var1, unioned.var2
FROM (
SELECT a.id, a.var1, a.var2
FROM table_A a
UNION ALL
SELECT b.id, b.var1, b.var2
from table_B b
) unioned;

I have similar query working. Just changing table name and column names. Try this. Hope this helps you.
create table new_table as
select
distinct
id, name
FROM
table1
union all
select
distinct
id,name
from
table2
;

Try this, it worked for me.
CREATE TABLE combined AS
SELECT id, var1, var2
FROM (
SELECT id, var1, var2
FROM table_A
UNION ALL
SELECT id, var1, var2
from table_B
) a;

Related

How can I count the amount of values in different columns in oracle plsql

For example, I have a table with these values:
ID
Date
Col1
Col2
Col3
Col4
1
01/11/2021
A
A
B
2
01/11/2021
B
B
The A and B values are dynamic, they can be other characters as well.
Now I need somehow to get to the result that id 1 has 2 occurences of A and one of B. Id 2 has 0 occurences of A and 2 occurences of B.
I'm using dynamic SQL to do this:
for v_record in table_cursor
loop
for i in 1 .. 4
loop
v_query := 'select col'||i||' from table where id = '||v_record.id;
execute immediate v_query into v_char;
if v_char = "any letter I'm checking" then
amount := amount + 1;
end if;
end loop;
-- do somehting with the amount
end loop;
But there has to be a better much more efficient way to do this.
I don't have that much knowledge of plsql and I really don't know how to formulate this question in google. I've looked into pivot, but I don't think that will help me out in this case.
I'd appreciate it if someone could help me out.
Assuming the number of columns would be fixed at four, you could use a union aggregation approach here:
WITH cte AS (
SELECT ID, Col1 AS val FROM yourTable UNION ALL
SELECT ID, Col2 FROM yourTable UNION ALL
SELECT ID, Col3 FROM yourTable UNION ALL
SELECT ID, Col4 FROM yourTable
)
SELECT
t1.ID,
t2.val,
COUNT(c.ID) AS cnt
FROM (SELECT DISTINCT ID FROM yourTable) t1
CROSS JOIN (SELECT DISTINCT val FROM cte) t2
LEFT JOIN cte c
ON c.ID = t1.ID AND
c.val = t2.val
WHERE
t2.val IS NOT NULL
GROUP BY
t1.ID,
t2.val;
This produces:
Demo

How to join hive tables based on condition of the joining column

We have a hive table like below:
num value
123 A
456 B
789 C
101 D
The joining table is:
num Symbols
123 ASC
456001 JEN
456002 JEN
456003 JEN
789001 CON
101 URB
Our expected result:
num value symbols
123 A ASC
456 B JEN
789 C CON
101 D URB
Currently we are joining the tables twice in order to get the results.
Like first time insert into some tmp table using the below query:
select
a.num,
a.value,
b.symbols
from mytable a
join mytable b on a.num = b.num;
This query is producing the results for keys 123,101.
Next, we are running another query like below:
select
a.num,
a.value,
b.symbols
from mytable a
join mytable b on CONCAT(a.num,'001') = b.num;
This query is producing the results for keys 456, 789.
These two queries results are inserted into some tmp hive table and we select the final results from the tmp table.
This looks a bad design overall. but I would like to know if there is a better way to achieve this. Thanks.
Query Result
for
Select
a.num
,a.value
,b.symbols
from
(select substr(num,3) as num, value from table)a
join
(select substr(num,3) as num, symbols from table) b
on a.num = b.num
a.num a.value b.symbols
3 A ASC
1 D URB
OK, just one sql can implement your requirement.see below, table a is the table with value column and table b is the table with the symbols column, the SQL:
select
distinct a.num,
a.value,
b.symbols
from
mytable1 a
join
mytable2 b on substr(cast(b.num as string),0,3) = cast(a.num as string)
If datatype of num is String then you can try with Substr
Select
a.num
,a.value
,b.symbols
from a join b on
substr(a.num,3) = substr(b.num,3)
Can you pls try this
Select
a.num
,a.value
,b.symbols
from
(select substr(num,3) as num, value from table)a
join
(select substr(num,3) as num, symbols from table) b
on a.num = b.num
Can you try with left semi join with above query as shown below.
Select
a.num,
a.value,
b.symbols
from
mytable1 a
Left semi join
mytable2 b on substr(cast(b.num as string),0,3) = cast(a.num as string)

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

With clause not working with union

My query result is a union of several queries. I am facing the below error when I use WITH clause within a union. Any ideas why?
select column1 from TABLE_A
union
with abcd as (select * from TABLE_B)
select column2 from TABLE_A A, abcd
where abcd.m_reference = A.m_reference
ORA-32034: unsupported use of WITH clause
32034. 00000 - "unsupported use of WITH clause"
*Cause: Inproper use of WITH clause because one of the following two reasons
1. nesting of WITH clause within WITH clause not supported yet
2. For a set query, WITH clause can't be specified for a branch.
3. WITH clause can't sepecified within parentheses.
*Action: correct query and retry
Encapsulate your WITH statement in a dummy select.
select column1 from TABLE_A
union
select * from (
with abcd as (select * from TABLE_B)
select column2 from TABLE_A A, abcd
where abcd.m_reference = A.m_reference
)
Just define the CTE first, before the actual UNION query. Then use it as you would a regular table:
with abcd as (select * from TABLE_B)
select column1 from TABLE_A
union
select column2
from TABLE_A A
inner join abcd
on abcd.m_reference = A.m_reference
You can use multiple CTE as follows:
with cte1 AS (...),
cte2 AS (...)
select * from ...
Encapsulating it is the way to go if you have multiple WITHs; for example I just had to do this monstrosity to quickly pull in data from ID numbers from an Excel sheet
select * from (
with childvendor as (
select vendornumber, name From vendor where vendornumber = '0000800727'
)
select
v.vendornumber as parentvendor,
v.name as parentname,
cv.vendornumber as childvendor,
cv.name as childname
From
vendor v, childvendor cv
where
v.vendornumber = '0000800004'
)
UNION ALL
select * from (
with childvendor as (
select vendornumber, name From vendor where vendornumber = '0000800042'
)
select
v.vendornumber as parentvendor,
v.name as parentname,
cv.vendornumber as childvendor,
cv.name as childname
From
vendor v, childvendor cv
where
v.vendornumber = '0000800035'
)
And so on

how to get exact string value from delimited column value match in oracle database

I have 2 tables
Table 1:
#######
ID Location
1 India
2 Australia
Table 2:
############
Name Locations
test1 India|North America
test2 Indiana|Australia
I used the below query to get the Name from table 2 if it contains Location in Locations of table 2.
select Name
from table2 t2 inner join table1 t1
on instr(t1.Location,t2.Locations,length(t1.Location)) >= 1;
But when executed it still gives me results for Indiana as well whereas it should just return me result for location India alone.
I tried using contains in query too, but contains takes second parameter as string but not as column name.
Is there any other approach on this?
regexps always help in such cases
with
table1 (id, location) as (
select 1, 'India' from dual union
select 2, 'Australia' from dual
),
table2 (name, locations) as (
select 'test1', 'India|North America' from dual union
select 'test2', 'Indiana|Australia' from dual
)
select *
from table2 join table1 on
regexp_like (locations, '(^|\|)' || location || '(\||$)')
Try to look up location with delimiter, like this:
select Name from table2 t2
inner join table1 t1 on instr(t2.Locations,t1.Location||'|') >= 1

Resources