如何通过不同分组汇总linq查询

时间:2019-06-13 14:25:35

标签: c# linq linq-to-entities

如何在linq中对不同的分组执行多个单独的聚合?

例如,我有一张桌子:

UNO     YOS Ranking Score
123456  1   42       17
645123  3   84       20

我想对此数据进行分组和未分组的一组聚合,例如:

var grouped = table.GroupBy(x => x.score )
                    .Select(x => new 
                    {
                        Score = x.Key.ToString(),
                        OverallAverageRank = x.Average(y => y.Ranking),
                        Year1RankAvg = x.Where(y => y.YOS == 1).Average(y => y.Ranking),
                        Year2RankAvg = x.Where(y => y.YOS == 2).Average(y => y.Ranking)
                        //...etc
                    });

我还想对相同的切片和整个数据执行不同的汇总(标准差)。

我无法弄清楚如何同时对YOS进行分组和不分组,尽管编译起来很好,但是在运行时,如果任何YOS平均值是,我都会得到“序列不包含任何元素”。内。

1 个答案:

答案 0 :(得分:0)

像任何编程一样,当您有一系列相似的项目时,请使用一个集合。在这种情况下,我将其保留为IEnumerable,但可以根据需要将其设置为ListDictionary的{​​{1}}。

YOS

如果您需要填写从1到最大(或其他一些数字)的年份范围,则可以修改答案:

var ans = table.GroupBy(t => t.Score)
               .Select(tg => new {
                    Score = tg.Key,
                   OverallAverageRank = tg.Average(t => t.Ranking),
                   YearRankAvgs = tg.GroupBy(t => t.YOS).Select(tyg => new { YOS = tyg.Key, RankAvg = tyg.Average(t => t.Ranking) })
               });

如果您愿意,可以修改原始的var ans2 = ans.Select(soryr => new { soryr.Score, soryr.OverallAverageRank, YearRankDict = soryr.YearRankAvgs.ToDictionary(yr => yr.YOS), YearMax = soryr.YearRankAvgs.Max(yr => yr.YOS) }) .Select(soryr => new { Score = soryr.Score, OverAverageRank = soryr.OverallAverageRank, YearRankAvgs = Enumerable.Range(1, soryr.YearMax).Select(yos => soryr.YearRankDict.ContainsKey(yos) ? soryr.YearRankDict[yos] : new { YOS = yos, RankAvg = 0.0 }).ToList() }); 以将ans返回为RankAvg,并在添加缺失年份时将double?替换为null