我有2个表A {int id,int grp},B {int aid,int cat}。
表B包含表A所属记录的类别列表,因此B.aid是引用A.id的外键。
A.id是表A的唯一主键。
B.cat包含1到5的类别编号,A.grp包含1到1000之间的数字。
表A有300万条记录,表B - 约500万条。
对于每个组A.grp我需要计算A组中包含B.cat的记录百分比,其中包含A.grp组中的记录数。
所以如果A:[{1,1},{2,1},{3,2}],B:[{1,3},{1,4},{2,3},{3 ,4}]然后查询结果应该是以下3列表: R {int grp,int cat,double percent}:[{1,3,100},{1,4,50},{2,4,100}]
如何在Linq中使用一个查询执行此操作?
希望A在该查询中只出现一次,因为我希望能够用A.Where(e =>一些复杂的表达式)替换A,而不会在该单个查询中多次复制它。
使用外键将表A和B导入到Linq到实体中,以便可以引用from a in A from b in a.B select b.cat
或from b in B select b.A.grp
答案 0 :(得分:1)
以下是生成所需结果的SQL代码:
with grp as (select a.grp,cnt=count(*) from a group by a.grp)
,cat as(select a.grp,b.cat,cnt=count( * ) * 100/grp.cnt
from a
join b on b.aid=a.id
join grp on grp.grp=a.grp
group by a.grp,b.cat,grp.cnt)
select * from cat
以下是产生所需结果的Linq代码:
var grp=
from a in db.A
group a by new{grp=a.grp}
;
var cat=
from a in db.A
from b in a.B
group b by new{a.grp,b.cat}
;
var q=from g in grp
join c in cat on g.Key.grp equals c.Key.grp
select new{g.Key.grp,c.Key.cat,percent=c.Count()*100/g.Count()};
但是有这样的事情会很好:
from a in db.A
group a by new{grp=a.grp} into grp
from g in grp
from c in g.B
group c by new{gcnt=grp.Count(),c.cat} into cat
from c in cat
select new{c.A.grp,c.cat,cnt=cat.Count()*100/cat.Key.gcnt}
但是它给了我以下运行时异常: 不支持嵌套查询。 Operation1 ='GroupBy'Operation2 ='MultiStreamNest'“
答案 1 :(得分:1)
您可以像这样组合查询
var query = from g in
(from a in db.A
group a by new
{
grp = a.grp
}
)
join c in
(from a in db.A
from b in a.B
group b by new
{
a.grp,
b.cat
}
)
on g.Key.grp equals c.Key.grp
select new
{
g.Key.grp,
c.Key.cat,
percent = c.Count() * 100 / g.Count()
};