Nested subquery not supported in hive - hadoop

We have tried the below query in hive. but getting the error. please help me to resolve this in any other way.
select count(1) as OpenItems from issues i , issue_statuses s
where s.id = i.status_id
and s.name NOT IN ('Closed','Passed','Rejected','On
Hold','Baselined','Completed')
and i.project_id IN
(select id from projects3 from
CASE WHEN ${projectname} = 'All' then id in
(select p.id from members m, projects3 p ,users_1 u
where m.project_id = p.id and u.id = m.user_id and u.status = '1'
and u.id IN
(select u1.id from users_1 u1, Supervisor_hierarchy s1 where u1.mail = s1.email and s1.name = ${Superisorname})
group by p.id)
WHEN (${projectname} <>'All' and ${SubProject projectname} ='All') then id
IN (select id from (select id from project_closure where parent_id in (select id from projects where name = ${projectname}) group by id)a)
WHEN (${SubProject projectname}<>'All' and ${projectname}<> 'All') then id
IN (select id from(select id from project_closure where id in (select id from projects where name = ${SubProject projectname}) group by id)a)
END
order by id)
error: 6:5 Unsupported SubQuery Expression 'id': SubQuery expression refers to both Parent and SubQuery expressions and is not a valid join condition.

I know it is late but posting for anyone who face this issue.
This issue occurs when we encounter one or more of the below limitations of Hive Subqueries.
In this scenario, the reference to the parent query is used in Group By clause which comes under the 4th limitation.
Hive Subquery Limitations
These subqueries are only supported on the right-hand side of an expression.
IN/NOT IN subqueries may only select a single column.
EXISTS/NOT EXISTS must have one or more correlated predicates.
References to the parent query are only supported in the WHERE clause of the subquery.
Source: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SubQueries

Related

Rewriting query with table join containing GROUP BY clause

Is it possible to rewrite the following query
SELECT CT.GROUP, CT.EMP_ID, HT.EFF_DT
FROM CURR_TABLE CT
JOIN (SELECT GROUP, EMP_ID, MAX(EFF_DT) AS EFF_DT
FROM HIST_TABLE
WHERE STAT = 'A'
GROUP BY GROUP, EMP_ID) HT ON CT.GROUP = HT.GROUP AND
CT.EMPID = HT.EMP_ID
WHERE CT.GROUP = :1
AND CT.EMP_ID = :2
in a way that is similar to CROSS JOIN style?
SELECT table1.column1, table2.column2...
FROM table1, table2 [, table3 ]
The reason is that I want to create such query in Peoplesoft, and the above can only be achieved by creating a separate view for the selection with the group by clause. I want to do this just in one query without creating additional views.
You may try writing your query as a single level join with an aggregation:
SELECT
CT.GROUP,
CT.EMP_ID,
MAX(HT.EFF_DT) AS EFF_DT
FROM CURR_TABLE CT
LEFT JOIN HIST_TABLE HT
ON CT.GROUP = HT.GROUP AND
CT.EMPID = HT.EMP_ID AND
HT.STAT = 'A'
WHERE
CT.GROUP = :1 AND
CT.EMP_ID = :2
GROUP BY
CT.GROUP,
CT.EMP_ID;
Note that GROUP is a reserved SQL keyword, and you might have to escape it with double quotes to make this query (or the one in your question) work on Oracle.

using subquery factoring result in where clause

Why can't I use a subquery factoring clause result in the where clause of as depicted in the following sql:
with rpt as(
select * from reports where caseid =
:case_id and rownum=1 order by created desc
)
select
distinct rt.trialid
from
report_trials rt
join
trial_genes tg on rt.id=tg.trialid
where
rt.reportid = rpt.id
and
tg.gene not in('TMB','MS')
The subquery is named rptand used in the select statement's where clause. When executed encountering the following error: ORA-00904: "RPT"."ID": invalid identifier
UPDATE:
In fact nested query for the same thing is also giving me the same issue. The nested subquery is only returning a single column value from a single row:
select
distinct rt.trialid
from
report_trials rt
join
trial_genes tg on rt.id=tg.trialid
where
rt.reportid = (select id from reports where caseid = :case_id and
rownum=1 order by created desc)
and
tg.gene not in('TMB','MS')
You missed to add the table rpt in your query, thus that error.
with rpt as(
select * from reports where caseid =
:case_id and rownum=1 order by created desc
)
select
distinct rt.trialid
from
report_trials rt
join
trial_genes tg on rt.id=tg.trialid
join
rpt on rt.reportid = rpt.id
where
tg.gene not in('TMB','MS')

Filter a query in Oracle

I have the following query
select a.empid, a.age, a.city, b.name
join supervisor b on a.supervisorid = b.empid
There is a chance that entries in "Supervisor" table may not be present in "Employee" table as an Employee
After forming the above query , i want to make "b.supervisorname" field as "null", if "b.supervisorid" not in "a.empid" column
EMPLOYEE TABLE:
EMPID--AGE--CITY--SUPERVISOR
1--12--A--123
2--21--B--1
3--23--C--2
Supervisor Table:
SUPERVISOR TABLE
EMPID--NAME
123--ABC
1--EFG
2-HIJ
OUTPUT:
EMPID--AGE--CITY--NAME
1--12--A--null
2--21--B--ABC
3--23--C--EFG
i dont want to use,
select a.empid, a.age, a.city, b.name
from employee a
join supervisor b on a.supervisorid =
(select empid
from supervisor
where empid in (select empid from employee))
as this kind of querying affects the performance
Is there any shortcut way to do it?
You should ALWAYS use explicit joins to avoid performance issues. And in general it helps to define a FROM clause in queries
The query below should work for you:
select
e.empid,
e.age,
e.city,
s.name
FROM
employee e
LEFT OUTER JOIN
supervisor s
on e.supervisor = s.empid

Invalid Identifier SQL

So i have this:
SELECT p.plantnaam,o.levcode,o.offerteprijs
FROM plant p, offerte o
JOIN (SELECT plantcode , MIN(offerteprijs) AS offprijs
FROM offerte
GROUP BY plantcode) s
ON s.plantcode = p.plantcode
AND s.offprijs = o.offerteprijs
ORDER BY p.plantnaam,l.levcode
Appearently on the 6th row, p.plantcode is suddenly magically an invalid identifier. Why is this? and why are all the others from the exact same table perfectly fine before that point?
The problem is that you are mixing JOINs. You have both implicit and explicit joins. The explicit JOIN syntax with the ON clause has a higher precedence over the implicit join with the commas. As a result the alias for the plant and the offerte tables will not be available in the ON clause. Try using the same JOIN type throughout:
SELECT p.plantnaam, o.levcode, o.offerteprijs
FROM
(
SELECT plantcode , MIN(offerteprijs) AS offprijs
FROM offerte
GROUP BY plantcode
) s
INNER JOIN plant p
ON s.plantcode = p.plantcode
INNER JOIN offerte o
ON s.offprijs = o.offerteprijs
ORDER BY p.plantnaam, l.levcode

Oracle : How to use if then in a select statement

select ma.TITLE,ma.ID as aid,ur.USER_ID
from LEO_MENU_ACTIVITY_RELATION mr
inner join LEO_MENU_MASTER mm on mm.ID=mr.MENU_ID
INNER join LEO_MENUACTIVITY ma on mr.ACTIVITY_ID=ma.ID
LEFT OUTER JOIN LEO_USER_RIGHTS ur on ma.ID=ur.MENU_RELATION_ID and ur.MENU_ID=mm.ID and ur.USER_ID='141'
where mm.ID='1'
UNION (SELECT
'List' as TITLE,
1 as ID,
case (WHEN ur.MENU_RELATION_ID=1 THEN NULL ELSE USER_ID END)as USER_ID
from
LEO_USER_RIGHTS)
In the UNION i want perform a conditional select like if ur.MENU_RELATION_ID=1 then the USER_ID should be selected as NULL otherwise the the original value from the 'LEO_USER_RIGHTS' table must be retrieved.
How can i do this ? Please help
Krishnik
If you want to combine in a UNION something based on the first table I think you can only do it by repeating the whole thing like this:
select ma.TITLE,ma.ID as aid,ur.USER_ID
from LEO_MENU_ACTIVITY_RELATION mr
inner join LEO_MENU_MASTER mm on mm.ID=mr.MENU_ID
INNER join LEO_MENUACTIVITY ma on mr.ACTIVITY_ID=ma.ID
LEFT OUTER JOIN LEO_USER_RIGHTS ur on ma.ID=ur.MENU_RELATION_ID and ur.MENU_ID=mm.ID and ur.USER_ID='141'
where mm.ID='1'
UNION (SELECT
'List' as TITLE,
1 as ID,
case (WHEN ur.MENU_RELATION_ID=1 THEN NULL ELSE USER_ID END)as USER_ID
from
LEO_MENU_ACTIVITY_RELATION mr
inner join LEO_MENU_MASTER mm on mm.ID=mr.MENU_ID
INNER join LEO_MENUACTIVITY ma on mr.ACTIVITY_ID=ma.ID
LEFT OUTER JOIN LEO_USER_RIGHTS ur on ma.ID=ur.MENU_RELATION_ID and ur.MENU_ID=mm.ID and ur.USER_ID='141'
where mm.ID='1'
)
If this is used often I would create a view to avoid duplicate code. In ORACLE (I do not know for other SQL dialects) there is a WITH statement enables you to make a sort of "temporary view".

Resources