转载Linq中GroupBy方法的使用总结
Group在SQL经常使用,通常是对一个字段或者多个字段分组,求其总和,均值等。
Linq中的Groupby方法也有这种功能。具体实现看代码:
假设有如下的一个数据集:
- public class StudentScore
- {
- public int ID { set; get; }
- public string Name { set; get; }
- public string Course { set; get; }
- public int Score { set; get; }
- public string Term { set; get; }
- }
- List<StudentScore> lst = new List<StudentScore>() {
- new StudentScore(){ID=1,Name="张三",Term="第一学期",Course="Math",Score=80},
- new StudentScore(){ID=1,Name="张三",Term="第一学期",Course="Chinese",Score=90},
- new StudentScore(){ID=1,Name="张三",Term="第一学期",Course="English",Score=70},
- new StudentScore(){ID=2,Name="李四",Term="第一学期",Course="Math",Score=60},
- new StudentScore(){ID=2,Name="李四",Term="第一学期",Course="Chinese",Score=70},
- new StudentScore(){ID=2,Name="李四",Term="第一学期",Course="English",Score=30},
- new StudentScore(){ID=3,Name="王五",Term="第一学期",Course="Math",Score=100},
- new StudentScore(){ID=3,Name="王五",Term="第一学期",Course="Chinese",Score=80},
- new StudentScore(){ID=3,Name="王五",Term="第一学期",Course="English",Score=80},
- new StudentScore(){ID=4,Name="赵六",Term="第一学期",Course="Math",Score=90},
- new StudentScore(){ID=4,Name="赵六",Term="第一学期",Course="Chinese",Score=80},
- new StudentScore(){ID=4,Name="赵六",Term="第一学期",Course="English",Score=70},
- new StudentScore(){ID=1,Name="张三",Term="第二学期",Course="Math",Score=100},
- new StudentScore(){ID=1,Name="张三",Term="第二学期",Course="Chinese",Score=80},
- new StudentScore(){ID=1,Name="张三",Term="第二学期",Course="English",Score=70},
- new StudentScore(){ID=2,Name="李四",Term="第二学期",Course="Math",Score=90},
- new StudentScore(){ID=2,Name="李四",Term="第二学期",Course="Chinese",Score=50},
- new StudentScore(){ID=2,Name="李四",Term="第二学期",Course="English",Score=80},
- new StudentScore(){ID=3,Name="王五",Term="第二学期",Course="Math",Score=90},
- new StudentScore(){ID=3,Name="王五",Term="第二学期",Course="Chinese",Score=70},
- new StudentScore(){ID=3,Name="王五",Term="第二学期",Course="English",Score=80},
- new StudentScore(){ID=4,Name="赵六",Term="第二学期",Course="Math",Score=70},
- new StudentScore(){ID=4,Name="赵六",Term="第二学期",Course="Chinese",Score=60},
- new StudentScore(){ID=4,Name="赵六",Term="第二学期",Course="English",Score=70},
- };
可以把这个数据集想象成数据库中的一个二维表格。
示例一
通常我们会把分组后得到的数据放到匿名对象中,因为分组后的数据的列不一定和原始二维表格的一致。当然要按照原有数据的格式存放也是可以的,只需select的时候采用相应的类型即可。
第一种写法很简单,只是根据下面分组。
- //分组,根据姓名,统计Sum的分数,统计结果放在匿名对象中。两种写法。
- //第一种写法
- Console.WriteLine("---------第一种写法");
- var studentSumScore_1 = (from l in lst
- group l by l.Name into grouped
- orderby grouped.Sum(m => m.Score)
- select new { Name = grouped.Key, Scores = grouped.Sum(m => m.Score) }).ToList();
- foreach (var l in studentSumScore_1)
- {
- Console.WriteLine("{0}:总分{1}", l.Name, l.Scores);
- }
- 第二种写法和第一种其实是等价的。
- //第二种写法
- Console.WriteLine("---------第二种写法");
- var studentSumScore_2 = lst.GroupBy(m => m.Name)
- .Select(k => new { Name = k.Key, Scores = k.Sum(l => l.Score) })
- .OrderBy(m => m.Scores).ToList();
- foreach (var l in studentSumScore_2)
- {
- Console.WriteLine("{0}:总分{1}", l.Name, l.Scores);
- }
示例二
当分组的字段是多个的时候,通常把这多个字段合并成一个匿名对象,然后group by这个匿名对象。
注意:groupby后将数据放到grouped这个变量中,grouped 其实是IGrouping<TKey, TElement>类型的,IGrouping<out TKey, out TElement>继承了IEnumerable<TElement>,并且多了一个属性就是Key,这个Key就是当初分组的关键字,即那些值都相同的字段,此处就是该匿名对象。可以在后续的代码中取得这个Key,便于我们编程。
orderby多个字段的时候,在SQL中是用逗号分割多个字段,在Linq中就直接多写几个orderby。
- //分组,根据2个条件学期和课程,统计各科均分,统计结果放在匿名对象中。两种写法。
- Console.WriteLine("---------第一种写法");
- var TermAvgScore_1 = (from l in lst
- group l by new { Term = l.Term, Course = l.Course } into grouped
- orderby grouped.Average(m => m.Score) ascending
- orderby grouped.Key.Term descending
- select new { Term = grouped.Key.Term, Course = grouped.Key.Course, Scores = grouped.Average(m => m.Score) }).ToList();
- foreach (var l in TermAvgScore_1)
- {
- Console.WriteLine("学期:{0},课程{1},均分{2}", l.Term, l.Course, l.Scores);
- }
- Console.WriteLine("---------第二种写法");
- var TermAvgScore_2 = lst.GroupBy(m => new { Term = m.Term, Course = m.Course })
- .Select(k => new { Term = k.Key.Term, Course = k.Key.Course, Scores = k.Average(m => m.Score) })
- .OrderBy(l => l.Scores).OrderByDescending(l => l.Term);
- foreach (var l in TermAvgScore_2)
- {
- Console.WriteLine("学期:{0},课程{1},均分{2}", l.Term, l.Course, l.Scores);
- }
示例三
Linq中没有SQL中的Having语句,因此是采用where语句对Group后的结果过滤。
- //分组,带有Having的查询,查询均分>80的学生
- Console.WriteLine("---------第一种写法");
- var AvgScoreGreater80_1 = (from l in lst
- group l by new { Name = l.Name, Term = l.Term } into grouped
- where grouped.Average(m => m.Score)>=80
- orderby grouped.Average(m => m.Score) descending
- select new { Name = grouped.Key.Name, Term = grouped.Key.Term, Scores = grouped.Average(m => m.Score) }).ToList();
- foreach (var l in AvgScoreGreater80_1)
- {
- Console.WriteLine("姓名:{0},学期{1},均分{2}", l.Name, l.Term, l.Scores);
- }
- Console.WriteLine("---------第二种写法");
- //此写法看起来较为复杂,第一个Groupby,由于是要对多个字段分组的,因此构建一个匿名对象,
- 对这个匿名对象分组,分组得到的其实是一个IEnumberable<IGrouping<匿名类型,StudentScore>>这样一个类型。
- Where方法接受,和返回的都同样是IEnumberable<IGrouping<匿名类型,StudentScore>>类型,
- 其中Where方法签名Func委托的类型也就成了Func<IGrouping<匿名类型,StudentScore>,bool>,
- 之前说到,IGrouping<out TKey, out TElement>继承了IEnumerable<TElement>,
- 因此这种类型可以有Average,Sum等方法。
- var AvgScoreGreater80_2 = lst.GroupBy(l => new { Name = l.Name, Term = l.Term })
- .Where(m => m.Average(x => x.Score) >= 80)
- .OrderByDescending(l=>l.Average(x=>x.Score))
- .Select(l => new { Name = l.Key.Name, Term = l.Key.Term, Scores = l.Average(m => m.Score) }).ToList();
- foreach (var l in AvgScoreGreater80_2)
- {
- Console.WriteLine("姓名:{0},学期{1},均分{2}", l.Name, l.Term, l.Scores);
- }
转载于:https://www.cnblogs.com/wphl-27/p/3480167.html
转载Linq中GroupBy方法的使用总结相关推荐
- LINQ中ForEach方法的使用
标签: linq 2016-06-25 12:47 409人阅读 评论(0) 收藏 举报分类: LINQ(5) 我の原创(113) 版权声明:本文为博主原创文章,未经博主允许不得转载.LINQ中For ...
- 用日志记录LINQ中的所有增删改的SQL语句的方法
我们知道LINQ中的增删改都要调用SubmitChanges方法,我们记录所有SQL的方式就是重写(override)DataContext中的SubmitChanges方法,为了避免每次修改dbml ...
- Linq中string转int的方法
Linq中string转int的方法 在做批量删除时,需把一串id值所对应的数据删除,调试出现问题: Linq语句中如果使用ToString()进行类型转换,编译时不会报错,但执行时会出现如下错误: ...
- matlab作动态函数曲线图,[转载]Matlab中使用Plot函数动态画图方法总结
本帖最后由 sonictl 于 2012-12-31 12:18 编辑 请删除我 清楚超靠靠靠 没办法,一会儿限制这不能发表,那不能发表的.... [转载]Matlab中使用Plot函数动态画图方法总 ...
- [转载] Java Challengers#1:JVM中的方法重载
参考链接: Java中自动装箱和扩展的方法重载 欢迎来到新的Java Challengers博客!本博客致力于挑战Java编程中的概念.掌握它们,你将成为一名技术娴熟的Java程序员. 本博客中的技术 ...
- 【转载】C#中AddRange方法往ArrayList集合末尾添加另一个集合
ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中,如果需要往一 ...
- 【转载】JS中bind方法与函数柯里化
原生bind方法 不同于jQuery中的bind方法只是简单的绑定事件函数,原生js中bind()方法略复杂,该方法上在ES5中被引入,大概就是IE9+等现代浏览器都支持了(有关ES5各项特性的支持情 ...
- [转载] Java中方法不可以有默认参数
参考链接: Java中的方法 Java中的方法不可以有默认参数,只能通过重载来实现: public class ParameterDefault { /** * @param args */ publ ...
- python中分组频率统计功能_python频数统计value_counts和groupby方法
python频数统计和groupby方法 频数统计 先用字典类型的数据创建一个DataFrame,test_data import pandas as pd test_data = pd.DataFr ...
最新文章
- Hadoop 2.2.0安装和配置lzo
- 【控制】《多智能体系统一致性与复杂网络同步控制》郭凌老师-第8章-Lurie 型动态网络自适应牵制控制
- 模拟实现mapset
- Matlab R2010a 32bit 绿色免安装版
- 计算机试讲教案模板范文,试讲教案模板1.doc
- mysql一样的查询在我本地很快但是线上很慢_MySQL大数据量分页查询方法及其优化...
- ORACLE Physical Standby 级联备库搭建
- 区块链软件开发:DApps的五个制胜要点
- python手机版做小游戏代码大全-用Python设计一个经典小游戏
- 3dmax java,基于Java 3D与3DS MAX的虚拟校园设计
- 【串口服务器】的桥接模式
- 源码编译Redis Desktop Manager参考
- html特殊符号怎么输入法,特殊符号怎么打出来?电脑特殊符号输入方法
- oracle12c创建监听,Oracle 12c为PDB创建专用监听
- stm32f4 ov7670 屏幕一直显示,OV7670 ERR 且MID(PID) 读出来是65535(0xffff)的解决办法
- 在VC中编程实现按钮的启用(enable)和禁用(disable)
- Python写个小游戏:速算24点(上)
- mysql数据库表中插入中文字段时报错 ‘\xCD\xF5\xBB\xAA‘
- 结对编程项目-四则运算阶段性总结
- computer_network CPT实验