groupby可以多个字段吗,group by用法多个字段
groupby java
groupby java是什么,让我们一起了解一下?
groupby的作用是通过一定的规则将一个数据集划分成若干个小的区域,然后针对若干个小区域进行数据处理,groupby核心用法是利用本身的某一列或多列内容进行分组聚合。
groupby的核心用法:
(1)根据DataFrame本身的某一列或多列内容进行分组聚合,(a)若按某一列聚合,则新DataFrame将根据某一列的内容分为不同的维度进行拆解,同时将同一维度的再进行聚合,(b)若按某多列聚合,则新DataFrame将是多列之间维度的笛卡尔积,即:新DataFrame具有一个层次化索引(由唯一的键对组成),例如:“key1”列,有a和b两个维度,而“key2”有one和two两个维度,则按“key1”列和“key2”聚合之后,新DataFrame将有四个group;
注意:groupby默认是在axis=0上进行分组的,通过设置axis=1,也可以在其他任何轴上进行分组。
(2)groupby,根据分组键的不同,有以下4种聚合方法:
1、分组键为Series。
(a)使用原df的子列作为Series。
df.groupby([ df[‘key1’], df[‘key2’] ]).mean()
(b)使用自定义的Series。
mapping={‘a’:‘red’,‘b’:‘red’,‘c’:‘blue’,‘d’:‘blue’,‘e’:‘red’,‘f’:‘orange’}
map_series=pd.Series(mapping)
people.groupby(map_series,axis=1).count()
2、分组键为列名。
df.groupby([ ‘key1’,‘key2’ ]).mean()
3、分组键为数组。
states=np.array([‘Ohio’, ‘California’, ‘California’, ‘Ohio’, ‘Ohio’])
years=np.array([2004,2005,2006,2005,2006]) #自定义数组
df[‘data1’].groupby( [ states,years ] ).mean()
4、分组键为字典。
mapping={‘a’:‘red’,‘b’:‘red’,‘c’:‘blue’,‘d’:‘blue’,‘e’:‘red’,‘f’:‘orange’} #自定义字典。
by_column=people.groupby(mapping,axis=1).sum() #指定axis=1,表示对列数据进行聚合分组。
5、分组键为函数。
例如:传入len函数(可以求取一个字符串长度数组),实现根据字符串的长度进行分组。
people.groupby(len).sum() #将字符串长度相同的行进行求和。
5、分组键为函数和数组、列表、字典、Series的组合。
引入列表list[ ] 将函数跟数组、列表、字典、Series混合使用作为分组键进行聚合,因为任何东西最终都会被转换为数组。
key_list=[‘one’,‘one’,‘one’,‘two’,‘two’] #自定义列表,默认列表顺序和df的列顺序一致。
people.groupby([ len,key_list ]).min()
6、分组键为具有多重列索引df 的列索引层次。
hier_df.groupby(level=‘cty’,axis=1).count() #利用参数level,指明聚合的层级。
代码示例说明:
将多个字段拼接成一个新字段,在使用Java8的groupBy进行分组。 Map?detailmap?=?details.stream() .collect(Collectors.groupingBy(d?-?fetchGroupKey(d)?)); private?String?fetchGroupKey(EntryDeliveryDetailywk?detail){ ????????return?detail.getSkuId().toString()? ????????+?detail.getItemsName()? ????????+?detail.getWarehouseId().toString()??? ????????+?detail.getSupplierId().toString(); ????}
如何在两个字段上使用GROUPBY并在SQL中计数
当然是可以的,例如:
表:table1(FId,Fclass,Fscore),用最高效最简单的SQL列出各班成绩最高的列表,显示班级,成绩两个字段。
select fclass,max(fscore) from table1 group by fclass,fid
Entity Framework怎么GroupBY多个字段
一、使用存储过程的必要性我们知道EF通过元数据,即概念模型(ConceptModel)、存储模型(StorageModel)和概念/存储映射(C/SMapping),和状态追踪(StateTracking)机制可以为基于模型的操作自动生成SQL。对于一些简单的项目开发,这是非常理想的,因为他们完全可以不用关注数据存储层面的东西,你可以采用一些完全不具有数据库知识的开发者。但是理想总归是理想,对于企业级开发来说,我们需要的是对数据库层面数据的操作有自己的控制。在这方面,我们可以随便举两个典型的场景:逻辑删除:对于一些重要的数据,我们可能需要让它们永久保存。当我们试图“删除”这些数据的时候,我们并不是将它们从数据表中移除(物理删除),而是为这条记录作一个已经被删除的标记;并发处理:为了解决相同的数据在获取和提交这段时间内被另一个用户修改或者删除,我们往往SQL层面增加并发控制的逻辑。比较典型的做法是在每一个表中添加一个VersionNo这样的字段,你可以采用TimeStamp,也可以直接采用INT或者GUID。在执行Update或者Delete的SQL中判断之前获取的VersionNo是否和当前的一致。让解决这些问题,就不能使用EF为我们自动生成的SQL,只有通过使用我们自定义的存储过程。二、实现存储过程自动匹配的必要条件本篇文章提供的存储过程自动映射机制是通过代码生成的方式完成的。说白了,就是读取原来的.edmx模型文件,通过分析在存储模型中使用的数据表,导入基于该表的CUD存储过程;然后再概念/存储映射节点中添加实体和这些存储过程的映射关系。那实现这样的代码生成,需要具有如下三个固定的映射规则。数据表名-存储过程名:这个映射关系帮助我们通过存储模型中的实体名找到对应CUD三个存储过程(如果实体是数据表);数据表列名-存储过程参数名:当存储过程被执行的时候,通过这个映射让概念模型实体某个属性值作为对应的参数;存储过程参数名-版本:当进行参数赋值的时候,通过这个映射决定是使用Original或者Current版本。在实际的开发过程中,这样的标准存储过程一般都是通过代码生成器生成的(在我的文章《创建代码生成器可以很简单:如何通过T4模板生成代码?[下篇]》中有过相应的实现),它们具有这样的映射关系。基于这三种映射关系,我定义了如下一个名为IProcedureNameConverter的接口。其中OperationKind是我自定义的一个表示CUD操作类型的枚举。1:publicinterfaceIProcedureNameConverter2:{3:stringGetProcedureName(stringtableName,OperationKindoperationKind);4:stringGetColumnName(stringparameterName);5:DataRowVersionGetVersion(stringparameterName);6:}7:8:publicenumOperationKind9:{10:Insert,11:Update,12:Delete13:}按照我们当前项目采用的命名规范,我定义了如下一个默认的DefaultNameConverter。它体现的是这样的映射关系,比如有个数据表明为T_USER(大写,单词之间用“_”隔开,并以T_为前缀),它对应的CUD存储过程名分别为:P_USER_I、P_USER_U和P_USER_D(大写,以代表存储过程的P_为前缀,后缀_I/U/D表示CUD操作类型,中间为去除前缀的表名)。如果列名为USER_ID,参数名为p_user_id(小写,加p_前缀)。如果需要用Original值为参数赋值,需要将p_前缀改成o_前缀(o_user_id)。1:publicclassDefaultNameConverter:IProcedureNameConverter2:{3:publicstringGetProcedureName(stringtableName,OperationKindoperationKind)4:{5:switch(operationKind)6:{7:caseOperationKind.Insert:8:returnstring.Format("P_{0}_I",tableName.Substring(2));9:caseOperationKind.Update:10:returnstring.Format("P_{0}_U",tableName.Substring(2));11:default:12:returnstring.Format("P_{0}_D",tableName.Substring(2));13:}14:}15:16:publicstringGetColumnName(stringparameterName)17:{18:returnparameterName.Substring(2).ToUpper();19:}20:21:publicDataRowVersionGetVersion(stringparameterName)22:{23:if(parameterName.StartsWith("o"))24:{25:returnDataRowVersion.Original;26:}27:else28:{29:returnDataRowVersion.Current;30:}31:}32:}三、通过T4生成新的.edmx模型我们采用的基于T4的代码生成,了解EF的应该对T4不会感到陌生了。如果对代码生成感兴趣的话,可以看看我的文章《与VS集成的若干种代码生成解决方案[博文汇总(共8篇)]》。这里利用借助于T4ToolBox这个开源工具箱,并采用SQLServerSMO获取存储过程信息。所有涉及到的文本转化都实现在如下一个ProcedureMappingTemplate类型中,由于内容较多,具体实现就忽略了,有兴趣的朋友可能下载源代码。ProcedureMappingTemplate具有两个构造函数的参数分别表示:源.edmx文件,服务器和数据库名,存储过程的Schema(默认为dbo)和具体的ProcedureNameConverter(默认为DefaultNameConverter)。1:publicclassProcedureMappingTemplate:Template2:{3:publicXmlDocumentSourceModel{get;privateset;}4:publicIProcedureNameConverterProcedureNameConverter{get;privateset;}5:publicDatabaseDatabase{get;privateset;}6:publicstringSchema{get;privateset;}7:8:publicProcedureMappingTemplate(stringsourceModelFile,stringserverName,stringdatabaseName);9:publicProcedureMappingTemplate(stringsourceModelFile,stringserverName,stringdatabaseName,10:IProcedureNameConverterprocedureNameConverter,stringschema);11:12:protectedvirtualXElementGenerateStorageModelNode();13:protectedvirtualXElementGenerateMappingNode();14:publicoverridestringTransformText()15:{16:XElementnewStorageModelNode=this.GenerateStorageModelNode();17:XElementnewMappingNode=this.GenerateMappingNode();18:19:XmlNodestorageModelNode=this.SourceModel.GetElementsByTagName("edmx:StorageModels")[0];20:storageModelNode.InnerXml=newStorageModelNode.Elements().ToArray()[0].ToString();21:22:XmlNodemappingNode=this.SourceModel.GetElementsByTagName("edmx:Mappings")[0];23:mappingNode.InnerXml=newMappingNode.Elements().ToArray()[0].ToString();24:25:this.WriteLine("");26:this.Write(this.SourceModel.DocumentElement.OuterXml.Replace("xmlns=\"\"",""));27:returnGenerationEnvironment.ToString();28:}29:}在使用过程中,你只需要在tt模板中创建这个ProcedureMappingTemplate对象,调用Render方法即可。1:2:3:4:5:6:7:8:9:四、看看生成出来的.emdx通过上面创建的TT模板(你指定的数据库中一定要存在具有相应映射关系的存储过程),新的.edmx模型文件会作为该tt文件的依赖文件被生成出来。而这个新生成的.edmx具有存储过程映射信息。具体来说,下面是原始的.edmx文件(只保留元数据节点)。1:2:3:4:5:6:7:8:9:10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51: