Left join to a SET using linq - 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 };

Related

Invalid identifier when using left outer join in Oracle

I wrote a query with Left outer join in oracle.But I execute the query I get ORA-00904: "b"."GROSS_DISCOUNT_AMOUNT": invalid identifier error.TableB contains net_discount_number and gross_discount_amount columns.
select
a.GSMNO GSMNO,
a.NET_AMOUNT net,
a.GROSS_AMOUNT gross,
sum(b.net_discount_amount) net_discount, sum(b.gross_discount_amount) gross_discount,
a.code code, a.seq_no
from tableA a
LEFT OUTER JOIN
(select id, code, seq_no, sum(gross_amount) gross_amount, sum(net_discount_amount), sum(gross_discount_amount) from tableB
group by id, code, seq_no)
b ON a.id = b.id and NVL(a.code,b.code) = NVL(b.code,-99) and
NVL(a._seq_no,-99) = NVL(b.seq_no,-99)
and a.gross_amount = b.gross_amount
where a.tvNo like '123% and gsmno ='1111111111'
group by
a.GSMNO,
a.NET_AMOUNT,
a.GROSS_AMOUNT,
a.code, a.seq_no
You haven't specified aliases for aggregate sums, it should be like this:
select
a.GSMNO GSMNO,
a.NET_AMOUNT net,
a.GROSS_AMOUNT gross,
sum(b.net_discount_amount) net_discount, sum(b.gross_discount_amount) gross_discount,
a.code code, a.seq_no
from tableA a
LEFT OUTER JOIN
(select id, code, seq_no,
sum(gross_amount) gross_amount,
sum(net_discount_amount) net_discount_amount,
sum(gross_discount_amount) gross_discount_amount
from tableB
group by id, code, seq_no)
b ON a.id = b.id and NVL(a.code,b.code) = NVL(b.code,-99) and
NVL(a._seq_no,-99) = NVL(b.seq_no,-99)
and a.gross_amount = b.gross_amount
where a.tvNo like '123% and gsmno ='1111111111'
group by
a.GSMNO,
a.NET_AMOUNT,
a.GROSS_AMOUNT,
a.code, a.seq_no

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 translate SQL to LINQ?

sql
select * from (select * from tabla limit 1) as a inner join table b on a.id = b.id where a.id = id
LINQ
from s in tableA
join c in (from a in tableB where a.id==id select a).FirstOrDefault() on s.id equals c.id
where s.id == id
select s
I want to translate this sql to linq but failed. How can I do translate?
I think this will do it, but you should check what sql is being generated by linq.
a = tableA.FirstOrDefault();
//First option
tableB.Where(xb => xb.id = a.id)
.Select(xb => new {a = a, b = xb})
.Where(abx => abx.a.id == id)
//Second option
tableB.Select(xb => new {a = a, b = xb})
.Where(abx => abx.a.id == id && abx.a.id = abx.b.id)

Resources