Multiple SubQuery expressions : Hive - hive

I am executing one hive query in my db in which i am joining 3 table(table1,table2,table3) and then comparing table1 year column with 3 other table(table4,table5,table6) using sub queries. I'm using below query.
select * from table1 A INNER JOIN table2 B ON A.id =b.id
inner JOIN table3 c ON A.id = c.id
and c.country ="India"
where (A.year)< (select year4 from table4)
and (A.year1)< (select year5 from table5 )
and (A.year1)< (select year5 from table5)
and (A.year1)< (select year6 from table6) limit 10;
but its giving me below error:
Error: Error while compiling statement: FAILED: SemanticException Line 0:-1 Unsupported SubQuery Expression
'year1': Only 1 SubQuery expression is supported.
someone please guide me how should i handle this.
EXPECTED OUTPUT

You need to put all tables in a join condition and then only you can compare year.
SELECT
*
FROM
TABLE1 A
INNER JOIN TABLE2 B ON A.ID =B.ID
INNER JOIN TABLE3 C ON A.ID = C.ID AND C.COUNTRY ="India"
INNER JOIN TABLE4 T4 ON T4.ID = A.ID AND A.YEAR < YEAR4
INNER JOIN TABLE5 T5 ON T5.ID = A.ID AND A.YEAR1 < YEAR5
INNER JOIN TABLE6 T6 ON T6.ID = A.ID AND A.YEAR1 < YEAR6
Pls check your SQL, year5 is compared twice.

Related

Oracle SQL - left join + left outer join

I am querying three tables. TABLE1 A and TABLE2 B have a one-to-one ratio on DEPTID. TABLE3 C, however, does not hold 0 values. I can successfully get COUNT to give me 0 values from TABLE3 C when doing a LEFT OUTER JOIN with TABLE1 A or TABLE2 B, but it gives me (null) instead of 0 when I join all three tables together. I need it to return 0 instead of (null). Any help is very much appreciated:
SELECT A.DEPTID, B.DEPT_NAME, SUM(C.HEAD_COUNT)
FROM TABLE1 A
LEFT JOIN TABLE2 B ON A.DEPTID = B.DEPTID
LEFT OUTER JOIN TABLE3 C ON A.POSITION_NUMBER = C.POSITION_NUMBER
GROUP BY A.DEPTID, B.DEPT_NAME
Here is what I am currently getting:
Dept 1: headcount 9
Dept 2: headcount 11
Dept 3: (null)
Use COALESCE() or NVL() to substitute 0 for NULL values:
SELECT A.DEPTID,
B.DEPT_NAME,
SUM(COALESCE( C.HEAD_COUNT, 0 ) )
FROM TABLE1 A
LEFT OUTER JOIN TABLE2 B
ON A.DEPTID = B.DEPTID
LEFT OUTER JOIN TABLE3 C
ON A.POSITION_NUMBER = C.POSITION_NUMBER
GROUP BY A.DEPTID,
B.DEPT_NAME

Query working in Teradata but not in Oracle

If I execute the following code I am able to get desired output; But in Oracle is am facing error :
SELECT NAME
FROM STUD
WHERE ID IN (
SEL DISTINCT TAB1.ID
FROM (
SEL A.ID
, B.SALARY
FROM Fr A
INNER JOIN PACK B ON A.ID = B.ID
) AS TAB1
INNER JOIN (
SEL A.FRIEND_ID
, B.SALARY
FROM Fr A
INNER JOIN PACK B ON A.FRIEND_ID = B.ID
) AS TAB2
ON TAB2.SALARY > TAB1.SALARY
)
;
Facing the below error in oracle :
ORA-00907: missing right parenthesis
You have two errors: SEL instead of SELECT and the usage of table aliases with AS keyword, which is not supported by Oracle
SELECT NAME
FROM STUD
WHERE ID IN (SELECT DISTINCT TAB1.ID FROM
(SELECT A.ID , B.SALARY
FROM
Fr A
INNER JOIN
PACK B
ON
A.ID = B.ID) TAB1
INNER JOIN
(SELECT A.FRIEND_ID , B.SALARY
FROM
Fr A
INNER JOIN
PACK B
ON
A.FRIEND_ID = B.ID
) TAB2
ON
TAB2.SALARY > TAB1.SALARY
)
Besides this, I think you don't need the DISTINCT in the inner query, given that you only use it in an IN clause

Compare 2 fields in different rows of the same table

I want to return results from a join where the birth_date of two+ records are the same, but the person_id's are not equal. I am using Oracle. So if I got 4 results where rows 1 & 2 have the same birth_date and different person_id, those rows would be returned. Where rows 3 & 4 have the same birth_date and same person_id, those rows would not be returned. I get results, but I want to filter our results where the birth_date of rows are equal, but the person_id is <>.
select t3.field1, t6.field2, t6.field3, t3.field4, t3.field5
from table1 t1
inner join table2 t2 on t1.#matching = t2.#matching
inner join table3 t3 on t3.#matching = t1.#matching
inner join table4 t4 on t4.#matching = t1.#matching
inner join table5 t5 on t5.#matching = t4.#matching
inner join table6 t6 on t6.#matching = t3.#matching
where t1.#requirement = 'xxx'
and t2.#requirement = 'xxx'
and t2.#requirement is null
and t4.#requirement = 'xxx'
and t5.#requirement = 'xxx'
and t1.#requirement ='xxx'
and t5.#requirement is null
order by t1.#field ASC;
SELECT a.birth_date, a.id, b.id
FROM some_table a, some_table b
WHERE a.birth_date = b.birth_date
AND a.id < b.id
Note the usage of < instead of the intuitive !=. This is done to prevent the same combination returning in different orders (e.g. (1,2) and (2,1)).
Have you tried to group your data by person_id.. This will put all the records with the same person_id into 1 record
The query would look something like this
SELECT a.birth_date, a.id, b.id
FROM some_table a, some_table b
WHERE a.birth_date = b.birth_date
AND a.id < b.id
GROUP BY a.id

Syntax for multiple joins in sql

Working on Oracle: I am attempting to do an inner self join, with a where clause, then take that result and do a left outer join on it:
(select * from table1 A
inner join
select * from table1 B
on A.id = B.id
where
A.id is not null and B.id is not null) C
left outer join
select * from table2 D
on C.id = D.id
Somehow I am syntactically challenged and can't make this work. Can't seem to find the right syntax anywhere.
Just the put the where clause at the end. The database will get it right:
select *
from table1 A
inner join table1 B on A.id = B.id
left join table2 D on D.id = A.id
where A.id is not null
In this case, we can take advantage of the logical transitive property for your id column joins and where clause.
Your second join needs to be joined to a query add a select * from at the beginning
select * from (select * from table1 A
inner join
select * from table1 B
on A.id = B.id
where
A.id is not null and B.id is not null) C
left outer join
select * from table2 D
on C.id = D.id

SQL Server - use columns from the main query in the subquery

Is there any way to get a column in real time, from a main query, and use it in a subquery?
Something like this: (Use A.item in the subquery)
SELECT item1, *
FROM TableA A
INNER JOIN
(
select *
from TableB B
where A.item = B.item
) on A.x = B.x;
Ok, here is the real thing:
I need to modify this existing query. It worked before, but now that the database changed, I need to do some modifications, add some comparisons. As you can see there are a lot of JOINS, and one of them is a subquery. I need to add a comparison from a column from the main query (from the table T0 for example) to the subquery (like this: T6.UnionAll_Empresa = T0.UnionALl_Empresa)
Select T0.UnionAll_Empresa,<STUFF>
from [UNION_ALL_BASES]..OINV T0 with (nolock)
inner join [UNION_ALL_BASES]..INV6 T1 with (nolock) on t0.DocEntry = t1.DocEntry and t0.UnionAll_Empresa = t1.UnionAll_Empresa
inner join
(
select
t1.CompanyID,
T2.CompanyDb,
t1.OurNumber,
T6.BankCode,
T6.BankName,
T3.[Description] Situation,
T1.[Status],
T5.Descrption nomeStatus,
T1.Origin,
T1.DocEntry,
T1.DocType,
T1.ControlKey,
T1.CardCode,
T4.[Description] ContractBank,
T1.PayMethodCode,
T1.DueDate,
T1.DocDate,
T1.InstallmentID,
T1.InstallmentValue,
T1.Correction,
T1.InterestContractural,
T1.FineContract,
T1.ValueAbatment,
T1.ValueDiscount,
T1.ValueFineLate,
T1.ValueInterestDaysOfLate,
T1.OtherIncreases,
T1.ValueInWords,
T1.ValueDocument,
T1.DigitalLine,
T1.Document
from [IntegrationBank]..BillOfExchange T1 with (nolock)
inner join [InterCompany2]..CompanyHierarchy T2 with (nolock) on T1.CompanyID = T2.ID
left join [IntegrationBank]..BillOfExchangeSituation T3 with (nolock) on T1.Situation = T3.ID
inner join [IntegrationBank]..ContractBank T4 with (nolock) on T1.ContractBank = T4.ID
inner join [IntegrationBank]..BoeStatus T5 with (nolock) on T1.[Status] = T5.ID
inner join [UNION_ALL_BASES]..ODSC T6 with (nolock) on T4.BankKey = T6.AbsEntry and **T6.UnionAll_Empresa = T0.UnionALl_Empresa** --I need to do this
where T1.[Status] <> 5
and T2.CompanyDb = **T0.UnionAll_Empresa** --I need to do this
) TBI on (T1.DocEntry = TBI.DocEntry and T1.InstlmntID = TBI.InstallmentID and TBI.DocType = T1.ObjType )
inner join [UNION_ALL_BASES]..OCTG T2 on T0.GroupNum = T2.GroupNum and T0.UnionAll_Empresa = T2.UnionAll_Empresa
inner join [UNION_ALL_BASES]..OSLP T3 on T0.SlpCode = T3.SlpCode and T0.UnionAll_Empresa = T3.UnionAll_Empresa
where not exists (select 1
from [UNION_ALL_BASES]..RIN1 A with (nolock)
inner join [UNION_ALL_BASES]..ORIN B with (nolock) on A.DocEntry = B.DocEntry and A.UnionAll_Empresa = B.UnionAll_Empresa
where A.BaseEntry = T0.DocEntry
and B.SeqCode = ''1'' )
You can user OUTER APPLY
SELECT *
FROM tbl1
OUTER APPLY ( SELECT TOP 1
currency_id,
SUM(taxrate) AS taxrate
FROM tbl2
WHERE wuptr.currency_id = tbl1.currency_id
GROUP BY tbl2.currencyid
)
You don't need a subquery for that:
SELECT item1, *
FROM TableA A
INNER JOIN
TableB B
ON A.item = B.item
AND A.x = B.x;
I can't think of a scenario where you would need to JOIN on a subquery with a filter like that where it wouldn't be equivalent to just reference the field directly in the outer query.
You can reference the outer table in the subquery in the WHERE clause, though:
SELECT <stuff>
FROM Table t
WHERE EXISTS (SELECT 1 from TableB B
WHERE t.id = b.id)
EDIT
For your actual code, just change the JOIN criteria to this:
) TBI on (T1.DocEntry = TBI.DocEntry
and T1.InstlmntID = TBI.InstallmentID
and TBI.DocType = T1.ObjType
AND TBI.CompanyDB = T0.UnionAll_Empresa )
If you want to join on to a subquery and "get a column in real-time"/ reference a column from the main query, then there is a trick to doing this.
You can't access the tables which are outside of the subquery if it's used as an aliased table, in other words, this SQL can never access A:
...
INNER JOIN
(
select *
from TableB B
where A.item = B.item
) on A.x = B.x;
The way to access A would be like this:
SELECT item1, *
FROM TableA A
INNER JOIN TableB on TableB.item = TableA.item and TableB.item in
(
select top 1 B.Item
from TableB B
where A.item = B.item
)
Just ignore the "top 1" piece, I just added that to show that there may a reason for doing a join like this.
So, basically if you want to reference an item from the query in the subquery, just move the subquery to the ON section of a join and use the IN keyword as illustrated above.
You can do this by naming the tables of the main query and the nested query.
For example:
SELECT continent, name, population FROM world x
WHERE population >= ALL
(SELECT population FROM world y
WHERE y.continent=x.continent
AND population>0)
reference: http://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial
Not sure why people are over-complicating this. #JNK is correct that you can move the predicate into the main query. For completeness, I will demonstrate.
You have two predicates in your subquery that reference T0:
T6.UnionAll_Empresa = T0.UnionAll_Empresa
T2.CompanyDb = T0.UnionAll_Empresa
The first is an INNER JOIN predicate on the table T6, and the second a WHERE clause - these are both "hard" filters, and will filter out results that don't match (unlike a LEFT OUTER JOIN which will simply set reference to that table's values to NULL).
Well, since T6.UnionAll_Empresa and T2.CompanyDb both need to filter against T0.UnionAll_Empresa, then we can simply change the INNER JOIN predicate on T6 to this:
T2.CompanyDb = T6.UnionAll_Empresa
Then, we can remove the WHERE clause in the subquery, and we can add this JOIN predicate to TBI in the main query:
TBI.CompanyDb = T0.UnionAll_Empresa
...making the entire query this:
Select T0.UnionAll_Empresa,<STUFF>
from [UNION_ALL_BASES]..OINV T0 with (nolock)
inner join [UNION_ALL_BASES]..INV6 T1 with (nolock) on t0.DocEntry = t1.DocEntry and t0.UnionAll_Empresa = t1.UnionAll_Empresa
inner join
(
select
t1.CompanyID,
T2.CompanyDb,
t1.OurNumber,
T6.BankCode,
T6.BankName,
T3.[Description] Situation,
T1.[Status],
T5.Descrption nomeStatus,
T1.Origin,
T1.DocEntry,
T1.DocType,
T1.ControlKey,
T1.CardCode,
T4.[Description] ContractBank,
T1.PayMethodCode,
T1.DueDate,
T1.DocDate,
T1.InstallmentID,
T1.InstallmentValue,
T1.Correction,
T1.InterestContractural,
T1.FineContract,
T1.ValueAbatment,
T1.ValueDiscount,
T1.ValueFineLate,
T1.ValueInterestDaysOfLate,
T1.OtherIncreases,
T1.ValueInWords,
T1.ValueDocument,
T1.DigitalLine,
T1.Document
from [IntegrationBank]..BillOfExchange T1 with (nolock)
inner join [InterCompany2]..CompanyHierarchy T2 with (nolock) on T1.CompanyID = T2.ID
left join [IntegrationBank]..BillOfExchangeSituation T3 with (nolock) on T1.Situation = T3.ID
inner join [IntegrationBank]..ContractBank T4 with (nolock) on T1.ContractBank = T4.ID
inner join [IntegrationBank]..BoeStatus T5 with (nolock) on T1.[Status] = T5.ID
inner join [UNION_ALL_BASES]..ODSC T6 with (nolock) on T4.BankKey = T6.AbsEntry and T2.CompanyDb = T6.UnionAll_Empresa
where T1.[Status] <> 5
) TBI on (T1.DocEntry = TBI.DocEntry and T1.InstlmntID = TBI.InstallmentID and TBI.DocType = T1.ObjType and TBI.CompanyDb = T0.UnionAll_Empresa)
inner join [UNION_ALL_BASES]..OCTG T2 on T0.GroupNum = T2.GroupNum and T0.UnionAll_Empresa = T2.UnionAll_Empresa
inner join [UNION_ALL_BASES]..OSLP T3 on T0.SlpCode = T3.SlpCode and T0.UnionAll_Empresa = T3.UnionAll_Empresa
where not exists (
select 1
from [UNION_ALL_BASES]..RIN1 A with (nolock)
inner join [UNION_ALL_BASES]..ORIN B with (nolock) on A.DocEntry = B.DocEntry and A.UnionAll_Empresa = B.UnionAll_Empresa
where A.BaseEntry = T0.DocEntry
and B.SeqCode = ''1''
)
This is entirely equivalent to what you have, and removes any reference to T0 from your subquery.
You can also use WITH
http://msdn.microsoft.com/en-us/library/ms175972.aspx