I want to get a result by typing subquery into the sum query.
The following code works when I write to Sql.
But on EF, how do I add another select at the top?
SQL
This code is work.
select
sum (data.rate)
from
(
SELECT
t1.Id,
(c.rate /
(SELECT COUNT(1) FROM [table4] AS [t4] WHERE ([t4].[FKId] = p1.Id))) as rate
FROM [table1] AS [t1]
INNER JOIN [table2] AS [t2] ON ([t1].[FKId] = [t2].[Id])
INNER JOIN [table3] AS [t3] ON ([t1].[FKId] = [t3].[Id]))
as data
C#
var data = await (
????
from t1 in ctx.table1
join t2 in ctx.table2 on new { t1.FKId} equals new { FKId = t2.Id}
join t3 in ctx.table3 on new { t1.FKId} equals new { FKId = t3.Id}
select new
{
rate = t3.Rate /
(from t4 in ctx.table4
where t4.FKId == t2.Id
select t4.Id)
.Count())
})
.SumAsync(sm => (double?)sm.rate ?? 0);
This c# code is not working.
Error:
Cannot perform an aggregate function on an expression containing an
aggregate or a subquery.
Per this answer, EF Core 3.0 still can't handle this situation (!).
However, you can translate the query without a subquery (effectively, using SelectMany) and it should work:
var ans = await (from t1 in ctx.table1
join t2 in ctx.table2 on t1.FKId equals t2.Id
join t3 in ctx.table3 on t1.FKId equals t3.Id
from t4 in ctx.table4
where t4.FkId == t2.Id
group t4.Id by new { t3.rate, t2.Id } into t2g
select t2g.Key.rate / t2g.Count()
)
.SumAsync();
Related
I am trying to bring this query in Snowflake. But, getting huge numbers with the last 3 inner joins which has same tables with different conditions.
select count(*) from table2; --5
select count(*) from table_3;--2824134
select count(*) from table1;--478015
Original Query:
select * from
from table1 d_tbl
inner join table2 r on r.number = d_tbl.number
inner join table_3 Zero on Zero.ID_I = r.id and Zero.time <= d_tbl.starttime and Zero.typeid in (7,19)
inner join table_3 first on first.ID_I = r.id and first.time <= Zero.time and first.typeid in (8,9)
inner join table_3 second on second.ID_I = r.id and second.time >= d_tbl.endtime and second.typeid in (8,9)
where d_tbl.mode = 0;
I tried breaking the queries into 3 parts.
create temp table tb1 as
select *
from table1 d_tbl
inner join table2 r on r.number = d_tbl.number ;
create temp table tb2 as
select ID_I , time as time as Zero_time,time as first_time,time as second_time
from table_3
where typeid in (8,9,7,19)
Note: saving the time column with different names for reference.
create temp table final_table as
select * from tb1 r
inner join tb2
on tb2.ID_I = r.id
where tb2.Zero_time <= r.starttime
and tb2.first_time <= Zero.time
and tb2.second_time >= r.endtime
Basically, I am trying to break the conditions in the joins to different parts.
This same logic has to be applied for different tables and do a union all for final table values.
Please help if this would work or let me know if this shall be handled with a better approach that executes faster.
TIA.
Try and convert following -
select * from
from table1 d_tbl
inner join table2 r on r.number = d_tbl.number
inner join table_3 Zero on Zero.ID_I = r.id
AND Zero.time <= d_tbl.starttime and Zero.typeid in (7,19)
inner join table_3 first on first.ID_I = r.id
AND first.time <= Zero.time and first.typeid in (8,9)
inner join table_3 second on second.ID_I = r.id
AND second.time >= d_tbl.endtime and second.typeid in (8,9)
where d_tbl.mode = 0;
To something like below -
select whatever-columns,
case when t3.time <= d_tbl.starttime
AND Zero.typeid in (7,19) then t3.time_1 end as zero_time,
case when t3.time <= zero_time
AND Zero.typeid in (8,9) then t3.time_1 end as first_time, --- snowflake allows to select/reference previous column
case when t3.time >= d_tbl.endtime
AND second.typeid in (8,9)then t3.time_1 end as second_time
from
table1 d_tbl
inner join table2 r on r.number = d_tbl.number
inner join table_3 t3 on t3.ID_I = r.id
where d_tbl.mode = 0;
This will help to reduce data-set being searched by avoiding multiple inner join on same table that has most records.
I have a T-SQL query that I need to change to an Access query. I tried a lot of times to change it but no success
UPDATE T1
SET Cap = ((txg*T2.Cap)/100 ),
IPi=(case when t2.TPi=1 then ((txg*T2.IPiTT)/100) else T1.IPi end)
FROM prg T1
JOIN main T2
ON T1.id = T2.id
where T1.Cap=0
Use IIF in Access SQL:
UPDATE
T1
SET
Cap = txg * T2.Cap / 100,
IPi = IIF(T2.TPi = 1, txg * T2.IPiTT / 100, T1.IPi)
FROM
prg AS T1
INNER JOIN
main AS T2
ON T1.id = T2.id
WHERE
T1.Cap = 0
I have below query which has multiple nested subqueries.
The requirement is to convert all the nested subqueries into joins with main outer select query.
select * from t1
where not exists (
select 1 from t2
join t21 on t21.c = t2.c
where t2.y = t1.y
and t2.x in (
select top 1 x from t3
join t31 on t31.d = t3.d
where t3.z = t2.z
and t3.a = t1.a
order by t3.b
)
)
Can anyone please help me achieve this?
I would like to write the following SQL queries into Linq To Entity queries.
SELECT *
FROM Table1
LEFT JOIN Table2 ON Table2.IdTable1 = Table1.Id
INNER JOIN Table3 ON Table3.IdTable2 = Table2.Id
SELECT *
FROM Table1
LEFT JOIN Table2 ON Table2.IdTable1 = Table1.Id
LEFT JOIN Table3 ON Table3.IdTable2 = Table2.Id
WHERE Table3.Id IS NULL
For the first one, I'm working on this :
var query = RepoTable1.AsQueryable();
[some query = query.Where(...)
query = query
.Join(RepoTable2.AsQueryable(), e => e.IdTable1, i => i.Id, (i, e) => i)
.GroupJoin(RepoTable3.AsQueryable(), c => c.IdTable2, eq => eq.Id, (eq, c) => eq);
There is something I don't understand about the Join.
Actually, "eq => eq.Id" should be of type "Table2", but it's "Table1".
If I change "(i, e) => i" to "(i, e) => e", I get an error of compilation because "query" is waiting "Table1" type.
And for the second query, I don't know how to add the "Where()" to the Join (actually, I'm mostly stuck with the first one)
Thanks in advance! Please tell me if this is not clear enough!
Final answer :
query = (from t1 in query
join t2 in RepoTable2.AsQueryable() on t1.Id equals t2.IdTable1 into joint1t2
from t2 in joint1t2.DefaultIfEmpty() // DefaultIfEmpty is used for left joins
join t3 in RepoTable3.AsQueryable() on t2.Id equals t3.IdT
select t1);
and for the second query :
query = (from t1 in query
join t2 in RepoTable2.AsQueryable() on t1.Id equals t2.IdTable1 into joint1t2
from t2 in joint1t2.DefaultIfEmpty() // DefaultIfEmpty is used for left joins
join t3 in RepoTable3.AsQueryable() on t2.Id equals t3.IdTable2 into joint2t3
from t3 in joint2t3.DefaultIfEmpty() // DefaultIfEmpty is used for left joins
where t3.Id== null
select t1);
I would recommend using query syntax (If you can't use navigation properties)
Your first query would look quite similar using this syntax
var query =
from t1 in RepoTable1.AsQueryable()
join t2 in RepoTable2.AsQueryable() on t1.Id equals t2.Id into t2g
from t2 in t2g.DefaultIfEmpty() //DefaultIfEmpty is used for left joins
join t3 in RepoTable3.AsQueryable() on t2.Id equals t3.Id
select new
{
t1, t2, t3
};
I have three tables
table1 -> xt1, yt1, zt1;
table2 -> xt2
table3 -> yt3, zt3
SELECT xt1, yt1, zt1
From table1, table3
Where xt1
NOT IN
(SELECT DISTINCT table1.xt1 FROM table2 INNER JOIN table1 ON
table1.xt1 = Replace(table2.xt2,',',''))
And table1.yt1 = table3.yt3
AND table1.zt1 = table3.zt3
it is working correctly but i take long time.
if i replace NOT IN with Not exists it return empty set.
SELECT xt1, yt1, zt1
From table1, table3
Where Not exists
(SELECT DISTINCT table1.xt1 FROM table2 INNER JOIN table1 ON
table1.xt1 = Replace(table2.xt2,',',''))
And table1.yt1 = table3.yt3
AND table1.zt1 = table3.zt3
the results of the second select should be 6 rows but it returns notiong with not exists.
also if i tried to change the compare part to
table1.xt1 != Replace(table2.xt2,',','') and remove the NOT IN
select it get outof memory error.
So is this the best way to write my query and why it return empty set with Not exists
thank you.
Ok, first of all, I changed your implicit join to an explicit one. Then I fixed the NOT EXISTS so it correlates to the outer table1:
SELECT t1.xt1, t1.yt1, t1.zt1
FROM table1 AS t1
INNER JOIN table3 AS t3
ON t1.yt1 = t3.yt3
AND t1.zt1 = t3.zt3
WHERE NOT EXISTS ( SELECT 1
FROM table2 AS t2
INNER JOIN table1 AS t1_1
ON t1_1.xt1 = REPLACE(t2.xt2,',','')
AND t1_1.xt1 = t1.xt1) ;
which can be simplified further to:
SELECT t1.xt1, t1.yt1, t1.zt1
FROM table1 AS t1
INNER JOIN table3 AS t3
ON t1.yt1 = t3.yt3
AND t1.zt1 = t3.zt3
WHERE NOT EXISTS ( SELECT 1
FROM table2 AS t2
WHERE t1.xt1 = REPLACE(t2.xt2,',','')
) ;
You need to select IN or exist depending upon the size of inner query. when there is a outer query and inner-sub-query, if the result of sub query is small, In is preferred as outer query is selected based upon result of sub-query.
if the result of sub-query is large, exist is preferred as outer query is evaluated first.