LINQ Left join on condition having 'OR' [duplicate] - linq

This question already has answers here:
Linq - left join on multiple (OR) conditions
(2 answers)
Closed 4 years ago.
I want to write this query in linq. Please help!!!
select * from TableA a
join Table B b
on a.ID = b.ID
left join TableC c
on b.ID=c.ID or b.ID = c.Text

You dont need always a Join.
var result = from a in TableA
from b in TableB
from c in TableC
where a.ID == b.ID && b.ID = c.ID || b.ID == c.Text

Related

What is the purpose of (+) operator in a where clause, other than outer joins, in Oracle SQL?

I have some very old Oracle SQL code I need to review, as per below and am trying to understand what the (+) operator is doing in the where clause after the first use of it
select *
from table_a a,
table b b
where
a.id = b.id (+)
and b.seq_nb (+) = 1
and b.type_cd (+) = 'DOLLR'
I thought (+) was a outer join equivalent, so
from table_a a,
table b b
where
a.id = b.id (+)
would be the same as
from table a a left outer join table b b on a.id=b.id
so how can you have outer joins to hard coded variables as below?
b.seq_nb (+) = 1
and b.type_cd (+) = 'DOLLR'
Any help would be greatly appreciated, thank you!
It's the same as:
select *
from table_a a
left outer join table_b b
on a.id = b.id
and b.type_cd = 'DOLLR'
and b.seq_nb = 1
Sometimes also referred to as a "filtered outer join".
It is equivalent to an outer join with a derived table:
select *
from table_a a
left outer join (
select *
from table_b
where b.type_cd = 'DOLLR'
and b.seq_nb = 1
) b on a.id = b.id

Run native sql query in JPA give difference result vs when run the same query directly in SQL tool

I have a native query like this:
WITH SOURCE_A AS (
SELECT a.ID FROM A a
WHERE a.SOME_THING > 1000
),
SOURCE_B AS (
SELECT b.ID FROM B b
INNER JOIN A a ON a.B_ID = b.ID
WHERE a.ID IN (SELECT * FROM SOURCE_A)
AND call_to_a_procedure(b.SOME_THING) = 1
),
SOURCE_C AS (
SELECT c.ID FROM C c
INNER JOIN B b ON b.C_ID = c.ID
WHERE b.ID IN (SELECTT * FROM SOURCE_B)
AND call_to_a_procedure(c.SOME_THING) = 1
)
SELECT re.CODE FROM RESULT re
INNER JOIN A a ON a.ID = re.ID_A
WHERE a.ID IN (SELECT * FROM SOURCE_A)
UNION
SELECT re.CODE FROM RESULT re
INNER JOIN B b ON b.ID = re.ID_B
WHERE b.ID IN (SELECT * FROM SOURCE_B)
UNION
SELECT re.CODE FROM RESULT re
INNER JOIN C c ON c.ID = re.ID_C
WHERE c.ID IN (SELECT * FROM SOURCE_C)
When I reun this query with query.getResultList() . Only the result of :
SELECT re.CODE FROM RESULT re
INNER JOIN A a ON a.ID = re.ID_A
WHERE a.ID IN (SELECT * FROM SOURCE_A)
is returned. The two UNION are ignored. But if I run the query directly in SQL tool like Oracle SQL developer or DBeaver, I get full UNION result.
JPA just silently ignore the UNION part, no error or exception.
UPDATE: It maybe because the call to call_to_a_procedure didn't work in jpa because if i remove the call to procedure, I can get the expected result.

How count table a data for every data of table a

I have three table A,B,C.
A table:
id,name
B table:
id,a_id,date
C table:
id,b_id,type(value is 0/1)
I want to print all A.name,A.id and C.countingdata by counting C data where C.type=1 using B table which has A table id
Result look like below:
A.id A.name C.countingdata
1 abc 4
2 vfd 2
3 fdg 0
Well, you can first inner join B and C, do the group by and get C.countingdata using count(). Another join on this subquery with B itself to accommodate the a_id
in the result set.
Now, you can do an inner join between A and the above subquery to get your results.
SQL:
select A.id, A.name, derived.countingData
from A
inner join (
select B.id as b_id,B.a_id,sub_data.countingData
from B
inner join (
select B.id,count(B.id) as countingData
from B
inner join C
on B.id = C.b_id
where C.type=1
group by B.id
) sub_data
on B.id = sub_data.id
) derived
on A.id = derived.a_id
You can find query as below:
Select
A.id
,A.name
,COUNT(C.id)
FROM A
JOIN B ON A.id = B.a_id
JOIN C ON B.id = C.b_id ANd C.type = 1
GROUP BY
A.id
,A.name

How to implement left join on data range in hive

I want to convert the below oracle logic to hive.
Logic:
Select a.id,a.name,b.desc from table a left join table b on
a.num between b.min_num and b.max_num;
Could any one help me out to achieve the above logic in hive.
With this solution you have the control on the performance.
b ranges are being split to sub-ranges, small as you want (x).
Too big x will practically cause a CROSS JOIN.
Too small x might generate a huge set from b (x=1 will generate all b ranges' values).
set hivevar:x=100;
select a.id
,a.name
,b.desc
from table_a as a
left join
(select a.id
,b.desc
from table_a as a
inner join
(select b.min_num div ${hivevar:x} + pe.pos as sub_range_id
,b.*
from table_b as b
lateral view
posexplode(split(space(cast (b.max_num div ${hivevar:x} - b.min_num div ${hivevar:x} as int)),' ')) pe
) as b
on a.num div ${hivevar:x} =
b.sub_range_id
where a.num between b.min_num and b.max_num
) b
on b.id =
a.id
;
select a.id
,a.name
,b.desc
from table_a as a
left join (select a.id
,b.desc
from table_a as a
cross join table_b as b
where a.num between b.min_num and b.max_num
) b
on b.id =
a.id
;
select a.id
,a.name
,b.desc
from table_a as a
left join (select b.min_num + pe.pos as num
,b.desc
from table_b as b
lateral view
posexplode(split(space(b.max_num-b.min_num),' ')) pe
) b
on b.num =
a.num
;

Left join to a SET using linq

In SQL, I would commonly inner join two or more tables to create a set and then left join to that set:
select *
from TableA
left outer join
TableB
inner join TableC on TableB.Id = TableC.TableBId
on TableA.Id = TableB.TableAId
What is the Linq equivalent of this? I'm using EF Code First.
Like this:
var result = from a in TableA
join b in TableB on a.Id equals b.TableAId into ab
from b in ab.DefaultIfEmpty()
join c in TableC on b.Id equals c.TableBId
select a;
I was able to achieve this by breaking it into two statements. First, make your inner join set, then left join to that set.
var bc = from b in TableB
join c in TableC on b.Id equals c.TableBId
select new { B = b, C = c };
var result = from a in TableA
from bcRow in bc.Where(row => a.Id equals row.B.TableAId).DefaultIfEmpty()
select new { A = a, B = bcRow.B, C = bcRow.C };

Resources