C#3.0入门系列(九)之GroupBy操作

摘要:
先来看下面的例子GroupBy操作中Select的匿名类varq=frompindb.Productsgrouppbyp.CategoryIDintogselectnew{CategoryID=g.Key,g};本例中,select操作中使用了匿名类。{if{foreach{}}}这里groupby的操作相对难理解些,主要原因,它包含了整个分组的具体信息,而不是简单的求和,取平均值等。SELECT[t1].[CategoryID],[t1].[value2]AS[ProductCount]FROMAS[t1]WHERE[t1].[value]˃=@p0--@p0:InputInt32[10]--Context:SqlProviderModel:AttributedMetaModelBuild:2.0.20612.0GroupBy操作中GroupBy的匿名类在第一次谈到匿名类时,我们就提到不光Select操作可以使用匿名类,其他操作符也可以。请参考C#3.0入门系列(六)-之OrderBy操作当用户既想按产品的分类,又想按供应商来做分组,该怎么办呢。

有朋友反馈说我提供的sample不能编译。大概是版本的问题,可以到http://msdn2.microsoft.com/en-us/bb330936.aspx下载for beta1的版本。本节接着讲groupby。
上一节,我们讲了如何理解groupby返回的结果。本节会延这个思路阐述下去。先来看下面的例子

GroupBy操作中Select的匿名类
C#3.0入门系列(九)之GroupBy操作第1张varq=frompindb.Products
C#3.0入门系列(九)之GroupBy操作第1张
grouppbyp.CategoryIDintog
C#3.0入门系列(九)之GroupBy操作第1张
selectnew{CategoryID=g.Key,g};
本例中,select操作中使用了匿名类。本系列中第一次提到匿名类是在http://www.cnblogs.com/126/archive/2006/12/20/503519.html一文中。本文将再一次,阐述匿名类的理解。所谓匿名类,其实质,并不是匿名,而是编译器帮你去创建了这么一个类,在用户看来,好像并没有去创建,此所谓匿名类。也就是说,编译器在编译时,还是有这个类的,这个类是编译器自己创建的,其名称是编译器界定的。 在上例的匿名类中,有2个property,一个叫CategoryID, 一个叫g。 大家要注意了,这个匿名类,其实质是对返回结果重新进行了包装。而那个叫做g的property,就封装了一个完整的分组。如图,仔细比较和上篇图的区别。
C#3.0入门系列(九)之GroupBy操作第4张
如果,使用下面的语句。
C#3.0入门系列(九)之GroupBy操作第1张varq=frompindb.Products
C#3.0入门系列(九)之GroupBy操作第1张
grouppbyp.CategoryIDintog
C#3.0入门系列(九)之GroupBy操作第1张
selectnew{CategoryID=g.Key,GroupSet=g};
只是把g重新命名为GroupSet.需要用下面的遍历,获取每个产品纪录。
C#3.0入门系列(九)之GroupBy操作第8张{
C#3.0入门系列(九)之GroupBy操作第9张
if(gp.CategoryID==7)
C#3.0入门系列(九)之GroupBy操作第10张C#3.0入门系列(九)之GroupBy操作第11张
C#3.0入门系列(九)之GroupBy操作第8张{
C#3.0入门系列(九)之GroupBy操作第9张
foreach(varpingp.GroupSet)
C#3.0入门系列(九)之GroupBy操作第10张C#3.0入门系列(九)之GroupBy操作第11张
C#3.0入门系列(九)之GroupBy操作第8张{
C#3.0入门系列(九)之GroupBy操作第9张
C#3.0入门系列(九)之GroupBy操作第18张}

C#3.0入门系列(九)之GroupBy操作第18张}

C#3.0入门系列(九)之GroupBy操作第20张}
这里groupby的操作相对难理解些,主要原因,它包含了整个分组的具体信息,而不是简单的求和,取平均值等。如果在最终结果中,也就是在select语句中,不包含g的全部信息,而只是g的聚合函数。又会是怎么样的一番风景呢?
GroupBy中的Max, Min, Sum, Average,Count
如果,只想取每类产品中,单价为最大,用T-sql该怎么办呢?是不是要这么来写
C#3.0入门系列(九)之GroupBy操作第1张SELECTMAX([t0].[UnitPrice])AS[MaxPrice],[t0].[CategoryID]
C#3.0入门系列(九)之GroupBy操作第1张
FROM[dbo].[Products]AS[t0]
C#3.0入门系列(九)之GroupBy操作第1张
GROUPBY[t0].[CategoryID]
我们来看看,dlinq如何来做同样的事情.如下,先按CategoryID归类,然后,只取CategoryID值和同类产品中单价最大的。
C#3.0入门系列(九)之GroupBy操作第1张varq=
C#3.0入门系列(九)之GroupBy操作第1张
frompindb.Products
C#3.0入门系列(九)之GroupBy操作第1张
grouppbyp.CategoryIDintog
C#3.0入门系列(九)之GroupBy操作第1张
selectnew{
C#3.0入门系列(九)之GroupBy操作第1张g.
Key,
C#3.0入门系列(九)之GroupBy操作第1张MaxPrice
=g.Max(p=>p.UnitPrice)
C#3.0入门系列(九)之GroupBy操作第1张};

在这里,Max函数只对每个分组进行操作。我们来看看其结果
C#3.0入门系列(九)之GroupBy操作第31张
呀,这次,dlinq并没有把组里所有的纪录都取出来的吗。(请参考http://www.cnblogs.com/126/archive/2006/09/01/486388.html一文中的方法,配置sample.) dlinq只是简单做了统计,并返回结果。
每类产品中,单价为最小的,

C#3.0入门系列(九)之GroupBy操作第1张varq=
C#3.0入门系列(九)之GroupBy操作第1张
frompindb.Products
C#3.0入门系列(九)之GroupBy操作第1张
grouppbyp.CategoryIDintog
C#3.0入门系列(九)之GroupBy操作第1张
selectnew{
C#3.0入门系列(九)之GroupBy操作第1张g.
Key,
C#3.0入门系列(九)之GroupBy操作第1张MinPrice
=g.Min(p=>p.UnitPrice)
C#3.0入门系列(九)之GroupBy操作第1张};
每类产品的价格平均值
C#3.0入门系列(九)之GroupBy操作第1张varq=
C#3.0入门系列(九)之GroupBy操作第1张
frompindb.Products
C#3.0入门系列(九)之GroupBy操作第1张
grouppbyp.CategoryIDintog
C#3.0入门系列(九)之GroupBy操作第1张
selectnew{
C#3.0入门系列(九)之GroupBy操作第1张g.
Key,
C#3.0入门系列(九)之GroupBy操作第1张AveragePrice
=g.Average(p=>p.UnitPrice)
C#3.0入门系列(九)之GroupBy操作第1张};
每类产品,价格之和
C#3.0入门系列(九)之GroupBy操作第1张varq=
C#3.0入门系列(九)之GroupBy操作第1张
frompindb.Products
C#3.0入门系列(九)之GroupBy操作第1张
grouppbyp.CategoryIDintog
C#3.0入门系列(九)之GroupBy操作第1张
selectnew{
C#3.0入门系列(九)之GroupBy操作第1张g.
Key,
C#3.0入门系列(九)之GroupBy操作第1张TotalPrice
=g.Sum(p=>p.UnitPrice)
C#3.0入门系列(九)之GroupBy操作第1张};
各类产品,数量之和
C#3.0入门系列(九)之GroupBy操作第1张varq=
C#3.0入门系列(九)之GroupBy操作第1张
frompindb.Products
C#3.0入门系列(九)之GroupBy操作第1张
grouppbyp.CategoryIDintog
C#3.0入门系列(九)之GroupBy操作第1张
selectnew{
C#3.0入门系列(九)之GroupBy操作第1张g.
Key,
C#3.0入门系列(九)之GroupBy操作第1张NumProducts
=g.Count()
C#3.0入门系列(九)之GroupBy操作第1张};
如果用OrderDetails表做统计,会更好些,因为,不光可以统计同一种产品,还可以统计同一订单。
接着统计,同各类产品中,断货的产品数量。使用下面的语句。
C#3.0入门系列(九)之GroupBy操作第1张varq=
C#3.0入门系列(九)之GroupBy操作第1张
frompindb.Products
C#3.0入门系列(九)之GroupBy操作第1张
grouppbyp.CategoryIDintog
C#3.0入门系列(九)之GroupBy操作第1张
selectnew{
C#3.0入门系列(九)之GroupBy操作第1张g.
Key,
C#3.0入门系列(九)之GroupBy操作第1张NumProducts
=g.Count(p=>p.Discontinued)
C#3.0入门系列(九)之GroupBy操作第1张};
在这里,count函数里,使用了Lambda表达式。在上篇中,我们已经阐述了g是一个组的概念。那在该Lambda表达式中的p,就代表这个组里的一个元素或对象,即某一个产品。还可以使用where条件来限制最终筛选结果
C#3.0入门系列(九)之GroupBy操作第1张varq=
C#3.0入门系列(九)之GroupBy操作第1张
frompindb.Products
C#3.0入门系列(九)之GroupBy操作第1张
grouppbyp.CategoryIDintog
C#3.0入门系列(九)之GroupBy操作第1张
whereg.Count()>=10
C#3.0入门系列(九)之GroupBy操作第1张
selectnew{
C#3.0入门系列(九)之GroupBy操作第1张g.
Key,
C#3.0入门系列(九)之GroupBy操作第1张ProductCount
=g.Count()
C#3.0入门系列(九)之GroupBy操作第1张};
这句在翻译成sql语句时,欠套了一层,在最外层加了条件。
C#3.0入门系列(九)之GroupBy操作第1张SELECT[t1].[CategoryID],[t1].[value2]AS[ProductCount]
C#3.0入门系列(九)之GroupBy操作第1张
FROM(
C#3.0入门系列(九)之GroupBy操作第1张
SELECTCOUNT(*)AS[value],COUNT(*)AS[value2],[t0].[CategoryID]
C#3.0入门系列(九)之GroupBy操作第1张
FROM[dbo].[Products]AS[t0]
C#3.0入门系列(九)之GroupBy操作第1张
GROUPBY[t0].[CategoryID]
C#3.0入门系列(九)之GroupBy操作第1张)
AS[t1]
C#3.0入门系列(九)之GroupBy操作第1张
WHERE[t1].[value]>=@p0
C#3.0入门系列(九)之GroupBy操作第1张
--@p0:InputInt32(Size=0;Prec=0;Scale=0)[10]
C#3.0入门系列(九)之GroupBy操作第1张--
Context:SqlProvider(Sql2005)Model:AttributedMetaModelBuild:2.0.20612.0

GroupBy操作中GroupBy的匿名类
第一次谈到匿名类时,我们就提到不光Select操作可以使用匿名类,其他操作符也可以。但是,OrderBy不支持。请参考C#3.0入门系列(六)-之OrderBy操作
当用户既想按产品的分类,又想按供应商来做分组,该怎么办呢。这时,我们就该使用匿名类。

C#3.0入门系列(九)之GroupBy操作第1张varcategories=
C#3.0入门系列(九)之GroupBy操作第1张
frompindb.Products
C#3.0入门系列(九)之GroupBy操作第1张
grouppbynew{p.CategoryID,p.SupplierID}intog
C#3.0入门系列(九)之GroupBy操作第1张
selectnew{g.Key,g};

在by后面,new出来一个匿名类。这里,Key其实质是一个类的对象,Key包含两个Property,一个是CategoryID,再一个是SupplierID ,要想取到具体CategoryID的值,需要g.Key.CategoryID,才能访问到。我们来看dlinq翻译的T-sql语句。

C#3.0入门系列(九)之GroupBy操作第1张SELECT[t0].[SupplierID],[t0].[CategoryID]
C#3.0入门系列(九)之GroupBy操作第1张
FROM[dbo].[Products]AS[t0]
C#3.0入门系列(九)之GroupBy操作第1张
GROUPBY[t0].[CategoryID],[t0].[SupplierID]
C#3.0入门系列(九)之GroupBy操作第1张
--Context:SqlProvider(Sql2005)Model:AttributedMetaModelBuild:2.0.20612.0

先按CategoryID,再按SupplierID ,和匿名类中的循序一样。
最后一个例子。

C#3.0入门系列(九)之GroupBy操作第1张varcategories=
C#3.0入门系列(九)之GroupBy操作第1张
frompindb.Products
C#3.0入门系列(九)之GroupBy操作第1张
grouppbynew{Criterion=p.UnitPrice>10}intog
C#3.0入门系列(九)之GroupBy操作第1张
selectg;

按产品单价是否大于10分类。其结果为两类,大于的是一类,小于及等于为另一类。好了,剩下的,大家自己多去领会。

TrackBack:http://www.cnblogs.com/126/archive/2007/07/10/812621.html

免责声明:文章转载自《C#3.0入门系列(九)之GroupBy操作》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Linux的分区0:虚幻引擎网络架构下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

MERGE

 Merge关键字是一个神奇的DML关键字。它在SQL Server 2008被引入,它能将Insert,Update,Delete简单的并为一句。MSDN对于Merge的解释非常的短小精悍:”根据与源表联接的结果,对目标表执行插入、更新或删除操作。例如,根据在另一个表中找到的差异在一个表中插入、更新或删除行,可以对两个表进行同步。”,通过这个描述,我...

SQL基础之 时间戳

本文转载:http://www.cnblogs.com/liuhh/archive/2011/05/14/2046544.html 一直对时间戳这个概念比较模糊,相信有很多朋友也都会误认为:时间戳是一个时间字段,每次增加数据时,填入当前的时间值。其实这误导了很多朋友。 1.基本概念 时间戳:数据库中自动生成的唯一二进制数字,与时间和日期无关的, 通常...

oracle 的用户管理 sqlplus的常用命令

创建用户:create user 用户名 identified by 密码; SQL> create user scw identified by 123; 用户已创建。 SQL> 在oracle中创建用户只能由管理员或者具有管理员的权限的用户创建 修改密码: 1.修改自己的密码: SQL> passw; 更改 SCW 的口令 旧口令...

SQL Server的复合索引学习

本文转载自:http://www.cnblogs.com/worfdream/archive/2010/05/21/1740752.html 概要什么是单一索引,什么又是复合索引呢? 何时新建复合索引,复合索引又需要注意些什么呢?本篇文章主要是对网上一些讨论的总结。一.概念 单一索引是指索引列为一列的情况,即新建索引的语句只实施在一列上。 用户可以在多个列...

ECSHOP模糊分词搜索和商品列表关键字飘红功能

ECSHOP联想下拉框 1、修改page_header.lbi模版文件,将搜索文本框修改为: <input name="keywords"type="text"id="keyword"value="<!--{if ($search_keywords neq "")}{$search_keywords|escape}--><!--...

MySQL查询截取分析

一、查询优化 1,mysql的调优大纲 慢查询的开启并捕获 explain+慢SQL分析 show profile查询SQL在Mysql服务器里面的执行细节和生命周期情况 SQL数据库服务器的参数调优 2,小表驱动大表 mysql的join实现原理是,以驱动表的数据为基础,“嵌套循环”去被驱动表匹配记录。驱动表的索引会失效,而被驱动表的索引有效。 #假...