请考虑以下表格:

重量:

City          Weight
--------------------
Tokyo          100
München        150
Köln           200

和数据:

ID       Country       City           Value
--------------------------------------------
1        Germany       München        10
2        Germany       München        20
3        Japan         Tokyo          12
4        Japan         Tokyo          20
5        Japan         Tokyo          8
6        Germany       Köln           5 
7        Germany       Köln           7
8        Germany       Köln           9

我想计算每个国家/地区的加权平均值:

我写了这样一个查询:

var MyResult = (from d in MyContext.Data
                join w in MyContext.Weight
                on d.City equals w.City
                select new {
                   d.Country,
                   d.City,
                   d.Value,
                   w.Weight
                }).GroupBy(p=>new {p.Country})
                  .Select(o=>new
                             {
                                 o.Key.Country,
                                 WeightedAverage = o.Sum(k=>k.Value * k.Weight) / o.Sum(k=>k.Weight)
                             })

但是它返回了错误的加权平均值.我想计算这个公式:

对于德国:

(10 * 150 + 20 * 150 + 5 * 200 + 7 * 200 + 9 * 200) / (150 + 150 + 200 + 200 + 200)

我怎样才能达到我想要的结果?

谢谢

推荐答案

请问你可以写SQL版本的查询吗?

由于您的数据以一种非常特殊的方式进行了反规范化,因此处理它的一种方法是创建子查询,该子查询将创建Country>;SUM(Weight)"映射".例如(因为SQL Sever似乎没有first个聚合函数,所以我在这里将其替换为max,这在Weight表中缺少某些数据的情况下将不能正常工作):

WITH WeightDict(Country, Weight) as (
  select Country, sum(Weight) as Weight
  from (
   select Country, w.City, max(Weight) as Weight
   from Weight w
   join Data d on w.City = d.City
   group by Country, w.City) sub
  group by Country
)

select d.Country, 1.0 * sum(d.Value * w.Weight)/max(wd.Weight) as WeightedAverage 
from Data d
join Weight w on w.City = d.City
join WeightDict wd on d.Country = wd.Country
group by d.Country

样本db fiddle - https://www.db-fiddle.com/f/fg1rXi5gTPjcGv7MS35TGB/1 .输出:

country weightedaverage
Germany 24.8571428571428571
Japan 40.0000000000000000

不确定这是否可能以EF Core LINQ查询的形式重写,但您可以try 分部分执行(即一个用于获取字典,另一个用于获取加权总和-sum(d.Value * w.Weight)),并在内存中执行最终联接.

Csharp相关问答推荐

.NET通过版本自动增量设置包版本

无法更改或使用C#(WinForms.NET)中的全局变量

使用其可能实现的基类和接口的属性的方法

一小时后,自定义缓存停止在App Insight中保存

. NET在上一个操作完成之前,在此上下文实例上启动了第二个操作

通过条件列表删除/更新EF Core 7中的实体的有效方法

在FilePath中搜索一个词,并根据First Match从左到右提取文件路径

为具有实体框架后端的Reaction项目 Select 正确的Visual Studio模板

如何通过属性初始化器强制初始化继承记录内的属性?

Blazor Web App WASM的两个独立项目令人困惑

在C#中反序列化/序列化具有混合元素顺序的XML时出现问题

Savagger使用Fastendpoint更改用户界面参数

在DoubleClick上交换DataGridViewImageColumn的图像和工具提示

Content WithTargetPath实际上是有效的MSBuild项吗?

如何在.NET MAUI中最大化GraphicsView的大小?

我找不到ASP.NET Web应用程序(.NET框架).已 Select .NET框架项目和项模板以及此组件(&Q;)

ReadOnlyMemory访问基础索引的替代方案

如何在一次数据库调用中为ASP.NET核心身份用户加载角色

c#在后台实现类型化数组

C#USB条形码 scanner 在第二次扫描时未写入行尾字符