Linq to Entities Non-Equal Join - linq

I must perform the following SQL command using IQueryable:
SELECT * FROM myTable t1
INNER JOIN myTable t2 ON t1.time = t2.time + 1
OR t1.time = t2.time + 2
OR t1.time = t2.time + 3;
Linq to Entities does not allow me to use IEqualityComparer, so I'm looking for some way to accomplish this Join.
Must use IQueryable and can not put conditions via Where as myTable has millions of records and implementation would be very slow:
qry = qry.Join(...).Where(...);
I need
qry = qry.Join(...);
Is there an alternative like IEqualityComparer for Linq to Entities?
Thank you!
Sorry my bad english!

I am not sure if this works with Lambda-Expression, but you can use Linq to achieve that:
var l = from i1 in conn.List1
from i2 in conn.List2
where
(
i1.time == i2.Time + 1
|| i1.time == i2.Time + 2
|| i1.time == i2.Time + 3
)
select new { i1, i2 }
Try also following:
var l = from i2 in conn.List2.Where(x => i1.time == x.Time + 1
|| i1.time == x.Time + 2
|| i1.time == x.Time + 3)
select new { i1, i2 }

Linq only supports equi-joins, so you will need to do this through a where clause.
That said, I would not expect a significant performance difference between a compound inner join and using a where clause - SQL should create similar (if not equal) plans for the following two queries:
SELECT *
FROM myTable t1
INNER JOIN myTable t2 ON t1.time = t2.time + 1
OR t1.time = t2.time + 2
OR t1.time = t2.time + 3;
SELECT *
FROM myTable t1 ,
myTable t2
WHERE t1.time = t2.time + 1
OR t1.time = t2.time + 2
OR t1.time = t2.time + 3;

Related

Oracle co related query?

How does co-related query works? Does inner query iterate according to outer query rows? Suppose I have student table with only 1 ID columns with vlaues 1, 2, 3. Can any body gives pictorial example?
select count(*)
from student s where s.sid < any (select s1.id from student s1 where s1.id < s.id);
The correlated subquery is (theoretically - without considering possible optimization) performed once for each row of the main table (s).
For the s.ID = 1 the subquery returns no row (s1.ID < 1 return nothing)
for the s.ID = 2 it returns 1 and (predicate s1.id < 2)
for the s.ID = 3 it returns 1,2
Therefore the first row (s.ID=1) is not selected (the subquery return no row),
for the second row (s.ID =2) the predicate is s.id < any ( 1 ) which is rewritten to s.id < 1 see rules for ANY
and the row is not selected as 2 < 1 is FALSE
for the third row (s.ID = 3) the predicate is s.id < any ( 1,2 ) which is rewritten to s.id < 1 OR s.id < 2 which is FLASE as well.
So the query
create table student as
select rownum id from dual connect by level <= 3;
select *
from student s where s.id < any (select s1.id from student s1 where s1.id < s.id);
return empty result (no rows).

BUG: ORA_00913 Oracle Error - Too many values

The below code is in stored procedure, and they told me to convert it into nested loops and try running it.
insert into PRICEVIEW_RATE_PLAN_PROC (
SSR_CODE
,CORRIDOR_PLAN_ID
,CORRIDOR_PLAN_DESCRIPTION
,USAGE_TYPE
,PRODUCT
,JURISDICTION
,PROVIDER
,RATE_PERIOD
,FLAGFALL
,RATE
,RATEBAND
,NUMSECS
,BAND_RATE
,ACTIVE_DT
,INACTIVE_DT
)
select /*+ use_hash(rate_usage_overrides,corridor_plan_id_values,product_elements,descriptions,jurisdictions,rate_usage_bands_overrides) */
distinct decode(a.corridor_plan_id, 0, '''', (
select c.short_display
from corridor_plan_id_values c
where a.corridor_plan_id = c.corridor_plan_id
)) as SSR_CODE
,a.corridor_plan_id as CORRIDOR_PLAN_ID
,decode(a.corridor_plan_id, 0, '''', (
select d.display_value
from corridor_plan_id_values d
where a.corridor_plan_id = d.corridor_plan_id
)) as CORRIDOR_PLAN_DESCRIPTION
,decode(a.type_id_usg, 0, '''', (
select f.description_text
from usage_types e
,descriptions f
where a.type_id_usg = e.type_id_usg
and e.description_code = f.description_code
)) as USAGE_TYPE
,decode(a.element_id, 0, '''', (
select h.description_text
from product_elements g
,descriptions h
where a.element_id = g.element_id
and g.description_code = h.description_code
)) as PRODUCT
,decode(a.jurisdiction, 0, '''', (
select j.description_text
from jurisdictions i
,descriptions j
where a.jurisdiction = i.jurisdiction
and j.description_code = i.description_code
)) as JURISDICTION
,decode(a.provider_class, 0, '''', (
select k.display_value
from provider_class_values k
where a.provider_class = k.provider_class
)) as PROVIDER
,decode(a.rate_period, '' 0 '', '''', (
select l.display_value
from rate_period_values l
where a.rate_period = l.rate_period
)) as RATE_PERIOD
,(a.FIXED_CHARGE_AMT / 100) + (a.ADD_FIXED_AMT / 10000000) as FLAGFALL
,(a.ADD_UNIT_RATE / 10000000) * 60 as RATE
,b.RATEBAND as RATEBAND
,b.NUM_UNITS as NUMSECS
,(b.UNIT_RATE / 10000000) * 60 as BAND_RATE
,a.ACTIVE_DT as ACTIVE_DT
,a.INACTIVE_DT as INACTIVE_DT
from rate_usage_overrides a
,rate_usage_bands_overrides b
where a.seqnum = b.seqnum(+);
I converted above code to nested loop and please find below converted nested loop and When I try to run this script below, it is prompting me an error: too many values. Can you tell me what exactly problem is
insert into PRICEVIEW_RATE_PLAN_PROC(
SSR_CODE,
CORRIDOR_PLAN_DESCRIPTION,
USAGE_TYPE,
PRODUCT,
JURISDICTION,
PROVIDER,
RATE_PERIOD,
FLAGFALL,
RATE,
RATEBAND,
NUMSECS,
BAND_RATE,
ACTIVE_DT,
INACTIVE_DT
) VALUES (
(select c.short_display AS SSR_CODE from rate_usage_overrides a,corridor_plan_id_values c where a.corridor_plan_id = c.corridor_plan_id),
(select d.display_value AS CORRIDOR_PLAN_DESCRIPTION from rate_usage_overrides a ,corridor_plan_id_values d where a.corridor_plan_id = d.corridor_plan_id),
(select f.description_text AS USAGE_TYPE from rate_usage_overrides a ,usage_types e, descriptions f where a.type_id_usg = e.type_id_usg and e.description_code = f.description_code ),
(select h.description_text AS PRODUCT from rate_usage_overrides a, product_elements g,descriptions h where a.element_id = g.element_id and g.description_code = h.description_code ),
(select j.description_text AS JURISDICTION from rate_usage_overrides a, jurisdictions i,descriptions j where a.jurisdiction = i.jurisdiction and j.description_code = i.description_code),
(select k.display_value AS PROVIDER from rate_usage_overrides a ,provider_class_values k where a.provider_class = k.provider_class),
(select l.display_value AS RATE_PERIOD from rate_usage_overrides a ,rate_period_values l where a.rate_period = l.rate_period),
(select (a.FIXED_CHARGE_AMT/100) + (a.ADD_FIXED_AMT/10000000) AS FLAGFALL from rate_usage_overrides a AS ACTIVE_DT),
(select (a.ADD_UNIT_RATE/10000000) * 60 AS RATE from rate_usage_overrides a),
(select b.RATEBAND AS RATEBAND from rate_usage_bands_overrides b),
(select b.NUM_UNITS AS NUMSECS from rate_usage_bands_overrides b),
(select (b.UNIT_RATE/10000000) * 60 AS BAND_RATE from rate_usage_bands_overrides b),
(select a.ACTIVE_DT,a.seqnum,b.seqnum AS ACTIVE_DT from rate_usage_overrides a, rate_usage_bands_overrides b where a.seqnum = b.seqnum(+)),
(select a.INACTIVE_DT,a.seqnum,b.seqnum AS INACTIVE_DT from rate_usage_overrides a, rate_usage_bands_overrides b where a.seqnum = b.seqnum(+))
Here is your mistake
(select a.ACTIVE_DT,a.seqnum,b.seqnum AS ACTIVE_DT from rate_usage_overrides a, rate_usage_bands_overrides b where a.seqnum = b.seqnum(+)),
(select a.INACTIVE_DT,a.seqnum,b.seqnum AS INACTIVE_DT from rate_usage_overrides a, rate_usage_bands_overrides b where a.seqnum = b.seqnum(+))
both the query will return 3 field but insert specify only one column that's why u are getting this error. and by the way this is not a bug
Run Individual queries with c.corridor_plan_id from 1st query on wards and check at least one query returns more than one value

get the sum of the maxs group by

I have this table
EquipmentId Value Date
1 2 11/04/2013
1 1 11/04/2013
2 3 11/04/2013
2 2 10/04/2013
2 5 10/04/2013
3 1 10/04/2013
3 3 11/04/2013
I want to group these items by date, and have a dictionary with the date as a key and the sum of the maxs of the all equipments values in that day
the result would be like this
[10/04/2013: 6] // 6 = 5 (as the max of values of the the equipmetId 2) + 1 (as the max of values of the the equipmetId 3)
[11/04/2013: 5] // 5 = 2(as the max of values of the the equipmetId 1) + 3(as the max of values of the the equipmetId 3)
I managed to make the query to get this without the sum, meaning for only one equipment.
var consumptionValues = (from c in context.ConsumptionSet
join pi in context.PropertiesInstanceSet on c.PropertiesInstanceID equals pi.PropertiesInstanceID
join ep in context.EquipmentPropertiesSet on pi.EquipmentPropertiesID equals ep.EquipmentPropertiesID
join e in context.EquipmentSet on ep.EquipmentID equals e.EquipmentID
where (e.EquipmentID == equipmentId && pi.ProprietesName == ProprietesName.Energy && c.Date <= DateTime.Now && c.Date >= firstDayDate)
group c by SqlFunctions.DatePart("weekday", c.Date) into grp
select new
{
dayOfWeek = (DayOfWeek)grp.Key.Value - 1,
value = grp.Max(c => c.Value),
}).ToDictionary(c => c.dayOfWeek.ToString(), c => c.value);
It's the complete query with all the joins, in the example I just gave a simplified example.
Is it possible to do this in one single query ?
I have to say I'm not sure it will work, but you should give it a shot:
var consumptionValues = (from c in context.ConsumptionSet
join pi in context.PropertiesInstanceSet on c.PropertiesInstanceID equals pi.PropertiesInstanceID
join ep in context.EquipmentPropertiesSet on pi.EquipmentPropertiesID equals ep.EquipmentPropertiesID
join e in context.EquipmentSet on ep.EquipmentID equals e.EquipmentID
where (e.EquipmentID == equipmentId && pi.ProprietesName == ProprietesName.Energy && c.Date <= DateTime.Now && c.Date >= firstDayDate)
group new { c, e } by SqlFunctions.DatePart("weekday", c.Date) into grp
select new
{
dayOfWeek = (DayOfWeek)grp.Key.Value - 1,
value = grp.GroupBy(i => i.e.EquipmentID).Sum(g => g.Max(i => i.c.Value)),
}).ToDictionary(c => c.dayOfWeek.ToString(), c => c.value);

Multiple Distincts with Linq

given the following information I have in a database table:
Col 1, Col2, Col3
1 , x , G
1 , y , H
2 , z , J
2 , a , K
2 , a , K
3 , b , E
What can I do in Linq (as I'm using Entity Framework) to get the following:
1 , x , G
1 , y , H
2 , z , J
2 , a , K
3 , b , E
You get the idea, I can do it in SQL just fine with the following:
Select Col 1, Col 2, Col 3
from Table
group by Col 1, Col 2, Col 3
No Idea how to do it in code as I can only find a way to do a distinct on one column.
Try this :
var Result = Context.Table.Select(C =>
new {
Col1 = C.Col1,
Col2 = C.Col2,
Col3 = C.Col3 }).Distinct();
Or alternately :
var Result = Context.Table.GroupBy(G=> new { G.Col1, G.Col2, G.Col3 })
.Select(C => new {
Col1 = C.Key.Col1,
Col2 = C.Key.Col2,
Col3 = C.Key.Col3
});
You could also use group by in linq on multiple fields:
myList.GroupBy(x=>new {x.Col1,x.Col2,x.Col3}).Select(x=>x.First()).ToList();
It is simple as, if you have only these three columns in the table.
var result = Context.Table.Distinct();
This will return your desired result.
If you have more columns then you can try as #Saeed Amiri stated in his answer.
#Kundan Singh Chouhan's alternative will give you the exact same sql query, which you state in your question

How to calculate multiple averages in one query in linq to entities

How to do this in linq to entities in one query?
SELECT avg(Column1), avg(Column2), ... from MyTable
where ColumnX = 234
??
You could do something like that:
var averages = myTable
.Where(item => item.ColumnX == 234)
.Aggregate(
new { count = 0, sum1 = 0.0, sum2 = 0.0 },
(acc, item) => new { count = acc.count + 1, sum1 = acc.sum1 + item.Column1, sum2 = acc.sum2 + item.Column2 },
acc => new { avg1 = acc.sum1 / acc.count, avg2 = acc.sum2 / acc.count });
Note the call to AsEnumerable() to force Aggregate to be executed locally (as EF probably doesn't know how to convert it to SQL) Actually it seems to work ;)
Alternatively, you could use this query:
var averages =
from item in table
where item.ColumnX == 234
group item by 1 into g
select new
{
Average1 = g.Average(i => i.Column1),
Average2 = g.Average(i => i.Column2)
};
The use of group by here is not very intuitive, but it's probably easier to read than the other solution. Not sure it can be converted to SQL though...

Resources