Group在SQL经常使用,通常是对一个字段或者多个字段分组,求其总和,均值等。

Linq中的Groupby方法也有这种功能。具体实现看代码:

假设有如下的一个数据集:

01.public class StudentScore
02.{
03.public int ID { setget; }
04.public string Name { setget; }
05.public string Course { setget; }
06.public int Score { setget; }
07.public string Term { setget; }
08.}
09.List<StudentScore> lst = new List<StudentScore>() {
10.new StudentScore(){ID=1,Name="张三",Term="第一学期",Course="Math",Score=80},
11.new StudentScore(){ID=1,Name="张三",Term="第一学期",Course="Chinese",Score=90},
12.new StudentScore(){ID=1,Name="张三",Term="第一学期",Course="English",Score=70},
13.new StudentScore(){ID=2,Name="李四",Term="第一学期",Course="Math",Score=60},
14.new StudentScore(){ID=2,Name="李四",Term="第一学期",Course="Chinese",Score=70},
15.new StudentScore(){ID=2,Name="李四",Term="第一学期",Course="English",Score=30},
16.new StudentScore(){ID=3,Name="王五",Term="第一学期",Course="Math",Score=100},
17.new StudentScore(){ID=3,Name="王五",Term="第一学期",Course="Chinese",Score=80},
18.new StudentScore(){ID=3,Name="王五",Term="第一学期",Course="English",Score=80},
19.new StudentScore(){ID=4,Name="赵六",Term="第一学期",Course="Math",Score=90},
20.new StudentScore(){ID=4,Name="赵六",Term="第一学期",Course="Chinese",Score=80},
21.new StudentScore(){ID=4,Name="赵六",Term="第一学期",Course="English",Score=70},
22.new StudentScore(){ID=1,Name="张三",Term="第二学期",Course="Math",Score=100},
23.new StudentScore(){ID=1,Name="张三",Term="第二学期",Course="Chinese",Score=80},
24.new StudentScore(){ID=1,Name="张三",Term="第二学期",Course="English",Score=70},
25.new StudentScore(){ID=2,Name="李四",Term="第二学期",Course="Math",Score=90},
26.new StudentScore(){ID=2,Name="李四",Term="第二学期",Course="Chinese",Score=50},
27.new StudentScore(){ID=2,Name="李四",Term="第二学期",Course="English",Score=80},
28.new StudentScore(){ID=3,Name="王五",Term="第二学期",Course="Math",Score=90},
29.new StudentScore(){ID=3,Name="王五",Term="第二学期",Course="Chinese",Score=70},
30.new StudentScore(){ID=3,Name="王五",Term="第二学期",Course="English",Score=80},
31.new StudentScore(){ID=4,Name="赵六",Term="第二学期",Course="Math",Score=70},
32.new StudentScore(){ID=4,Name="赵六",Term="第二学期",Course="Chinese",Score=60},
33.new StudentScore(){ID=4,Name="赵六",Term="第二学期",Course="English",Score=70},
34.};

可以把这个数据集想象成数据库中的一个二维表格。

示例一

通常我们会把分组后得到的数据放到匿名对象中,因为分组后的数据的列不一定和原始二维表格的一致。当然要按照原有数据的格式存放也是可以的,只需select的时候采用相应的类型即可。

第一种写法很简单,只是根据下面分组。

01.//分组,根据姓名,统计Sum的分数,统计结果放在匿名对象中。两种写法。
02.//第一种写法
03.Console.WriteLine("---------第一种写法");
04.var studentSumScore_1 = (from l in lst
05.group l by l.Name into grouped
06.orderby grouped.Sum(m => m.Score)
07.select new { Name = grouped.Key, Scores = grouped.Sum(m => m.Score) }).ToList();
08.foreach (var l in studentSumScore_1)
09.{
10.Console.WriteLine("{0}:总分{1}", l.Name, l.Scores);
11.}
12.第二种写法和第一种其实是等价的。
13.//第二种写法
14.Console.WriteLine("---------第二种写法");
15.var studentSumScore_2 = lst.GroupBy(m => m.Name)
16..Select(k => new { Name = k.Key, Scores = k.Sum(l => l.Score) })
17..OrderBy(m => m.Scores).ToList();
18.foreach (var l in studentSumScore_2)
19.{
20.Console.WriteLine("{0}:总分{1}", l.Name, l.Scores);
21.}

示例二

当分组的字段是多个的时候,通常把这多个字段合并成一个匿名对象,然后group by这个匿名对象。

注意:groupby后将数据放到grouped这个变量中,grouped 其实是IGrouping<TKey, TElement>类型的,IGrouping<out TKey, out TElement>继承了IEnumerable<TElement>,并且多了一个属性就是Key,这个Key就是当初分组的关键字,即那些值都相同的字段,此处就是该匿名对象。可以在后续的代码中取得这个Key,便于我们编程。

orderby多个字段的时候,在SQL中是用逗号分割多个字段,在Linq中就直接多写几个orderby。

01.//分组,根据2个条件学期和课程,统计各科均分,统计结果放在匿名对象中。两种写法。
02.Console.WriteLine("---------第一种写法");
03.var TermAvgScore_1 = (from l in lst
04.group l by new { Term = l.Term, Course = l.Course } into grouped
05.orderby grouped.Average(m => m.Score) ascending
06.orderby grouped.Key.Term descending
07.select new { Term = grouped.Key.Term, Course = grouped.Key.Course, Scores = grouped.Average(m => m.Score) }).ToList();
08.foreach (var l in TermAvgScore_1)
09.{
10.Console.WriteLine("学期:{0},课程{1},均分{2}", l.Term, l.Course, l.Scores);
11.}
12.Console.WriteLine("---------第二种写法");
13.var TermAvgScore_2 = lst.GroupBy(m => new { Term = m.Term, Course = m.Course })
14..Select(k => new { Term = k.Key.Term, Course = k.Key.Course, Scores = k.Average(m => m.Score) })
15..OrderBy(l => l.Scores).OrderByDescending(l => l.Term);
16.foreach (var l in TermAvgScore_2)
17.{
18.Console.WriteLine("学期:{0},课程{1},均分{2}", l.Term, l.Course, l.Scores);
19.}

示例三

Linq中没有SQL中的Having语句,因此是采用where语句对Group后的结果过滤。

01.//分组,带有Having的查询,查询均分>80的学生
02.Console.WriteLine("---------第一种写法");
03.var AvgScoreGreater80_1 = (from l in lst
04.group l by new { Name = l.Name, Term = l.Term } into grouped
05.where grouped.Average(m => m.Score)>=80
06.orderby grouped.Average(m => m.Score) descending
07.select new { Name = grouped.Key.Name, Term = grouped.Key.Term, Scores = grouped.Average(m => m.Score) }).ToList();
08.foreach (var l in AvgScoreGreater80_1)
09.{
10.Console.WriteLine("姓名:{0},学期{1},均分{2}", l.Name, l.Term, l.Scores);
11.}
12.Console.WriteLine("---------第二种写法");
13.//此写法看起来较为复杂,第一个Groupby,由于是要对多个字段分组的,www.it165.net 因此构建一个匿名对象,
14.对这个匿名对象分组,分组得到的其实是一个IEnumberable<IGrouping<匿名类型,StudentScore>>这样一个类型。
15.Where方法接受,和返回的都同样是IEnumberable<IGrouping<匿名类型,StudentScore>>类型,
16.其中Where方法签名Func委托的类型也就成了Func<IGrouping<匿名类型,StudentScore>,bool>,
17.之前说到,IGrouping<out TKey, out TElement>继承了IEnumerable<TElement>,
18.因此这种类型可以有Average,Sum等方法。
19.var AvgScoreGreater80_2 = lst.GroupBy(l => new { Name = l.Name, Term = l.Term })
20..Where(m => m.Average(x => x.Score) >= 80)
21..OrderByDescending(l=>l.Average(x=>x.Score))
22..Select(l => new { Name = l.Key.Name, Term = l.Key.Term, Scores = l.Average(m => m.Score) }).ToList();
23.foreach (var l in AvgScoreGreater80_2)
24.{
25.Console.WriteLine("姓名:{0},学期{1},均分{2}", l.Name, l.Term, l.Scores);
26.

本文转载自:http://www.it165.net/pro/html/201301/4521.html

Linq分组,linq方法分组的更多相关文章

  1. 如何使用linq操作datatable进行分组

    使用微软.net的孩子们应该都知道linq吧,要知道linq可是其他高级语言没有的技术,比如php,java等等,但是起初我对linq的认识只是停留在对 list<> 的泛型集合进行操作, ...

  2. LINQ按多列分组(Group By)并计算总和(Sum) (转载)

    来源:https://codedefault.com/2018/group-by-multiple-columns-and-sum-in-csharp .NET[C#]LINQ按多列分组(Group ...

  3. Linq的Distinct方法的扩展

    原文地址:如何很好的使用Linq的Distinct方法 Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1&qu ...

  4. Linq lambda 匿名方法

    课程6 委托.匿名方法.Lambda表达式.Linq查询表达式 上课日志1 一.委托的基本认识 提问:能不能把方法作为参数传递??? 也即是能不能声明一个能存放方法的变量呢——委托. 委托是一种数据类 ...

  5. CASE函数 sql server——分组查询(方法和思想) ref和out 一般处理程序结合反射技术统一执行客户端请求 遍历查询结果集,update数据 HBuilder设置APP状态栏

    CASE函数   作用: 可以将查询结果集的某一列的字段值进行替换 它可以生成一个新列 相当于switch...case和 if..else 使用语法: case 表达式/字段 when 值 then ...

  6. 21扩展IEnumerable<T>泛型接口自定义LINQ的扩展方法

    LINQ方法实际上是对IEnumerable<TSource>的扩展,如图:   本篇自定义一个MyWhere方法,达到与Where相同的效果.     使用LINQ自带的Where方法 ...

  7. “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法

    “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> 接口或 IQueryable& ...

  8. Linq Enumerable.Distinct方法去重

    Enumerable.Distinct 方法 是常用的LINQ扩展方法,属于System.Linq的Enumerable方法,可用于去除数组.集合中的重复元素,还可以自定义去重的规则. 有两个重载方法 ...

  9. day23_1-re模块之转义字符、分组、方法

    #!/usr/bin/env python# -*- coding:utf-8 -*-# ------------------------------------------------------- ...

随机推荐

  1. Countries

    Countries 题目链接:http://hihocoder.com/problemset/problem/1391 预处理+双指针 首先将A->B,B->A的导弹全部转化为B-> ...

  2. 第八十节,CSS3边框图片效果

    CSS3边框图片效果 学习要点: 1.属性初探 2.属性解释 3.简写和版本 本章主要探讨HTML5中CSS3中边框图片背景的效果,通过这个新属性让边框更加的丰富多彩. 一.属性解释     CSS3 ...

  3. HDU 1896 Stones (优先队列)

    Problem Description Because of the wrong status of the bicycle, Sempr begin to walk east to west eve ...

  4. JS学习之路,菜鸟总结的注意事项及错误更正

    JavaScript 是一种面向对象的动态语言,它的语法来源于 Java 和 C,所以这两种语言的许多语法特性同样适 用于 JavaScript.需要注意的一个主要区别是 JavaScript 不支持 ...

  5. HDU 2102 A计划(DFS)

    题目链接 Problem Description 可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸的她再一次面临生命的考验.魔王已经发出消息说将在T时刻吃掉公主,因为他听信谣言说吃公主 ...

  6. Spark 倾斜连接

    [数据倾斜出现的原因] 并行计算中,我们总希望分配的每一个任务(task)都能以相似的粒度来切分,且完成时间相差不大.但是由于集群中的硬件和应用的类型不同.切分的数据大小不一,总会导致部分任务极大地拖 ...

  7. hdu 1003,nefu 728 max sum

    Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub ...

  8. Linux Root密码忘记怎么办?用Vultr vps教程演示重置root密码

    使用vultr免费提供的snapshots功能,可以轻松备份vps镜像,通常会碰到一个问题:恢复镜像后,vps的root密码失效了.正常情况下,root密码是镜像文件里的root密码,在某些情况下,由 ...

  9. solr定时增量索引

    当数据库的数据发生改变的时候,我们不想手动的去重新添加数据库的数据导solr索引库中,所以用到定时添加索引.增删改的数据.现在写的这些都是基于我之前做的一步步到这来的. 将solr/dist下的sol ...

  10. 【编码问题】if,for语句与中文编码

    1. 首先先来说说中文的问题.众所周知,作死的python经常和中文过不去 每次,开头必须声明 # coding: utf-8 或者是 # -*- coding: utf-8  -*- 然而,被坑过的 ...