集算器可以很方便地实现常见的几种内存分组,比如等值分组、对位分组、枚举分组,下面用相应的例子来说明。
等值分组
等值分组的分组依据是本数据集的字段(或字段派生的计算列),每个组都是原数据集的子集。
例子描述:将销售订单按照订单年份进行分组。
数据描述:订单数据如下:
上述数据集(序表)可以从数据库或文件读入,比如:
A1=file("E:/sales.txt")[email protected]()
集算器代码
A2=A1.group(year(OrderDate))
计算结果
代码解读
- 本例中,分组依据来自于订单日期(OrderDate),通过year(OrderDate)可以将订单日期计算成年份,分组后每一年的数据归为一组。
- 分组字段可以是多个。比如重新按照年份、销售员分组,将不同年份不同销售员的数据归为一组,代码如下:
A1.group(year(OrderDate),SellerId)
3. 分组后的数据经常要进行聚合运算,比如根据A2计算出每年的销售额,代码如下:
A2.new(year(OrderDate):y,~.sum(Amount):a)
计算结果是:
也可以将分组和汇总这两步用一个groups函数来实现:
A1.groups(year(OrderDate):y;sum(Amount):a)
当然,有时为了代码重用和提高计算效率,我们不得不把分组和汇总分开,比如对A2的其中一个组进行过滤,另一个组进行关联计算。再比如:汇总后发现某个分组的数据比较异常,值得深入研究,此时就可以利用原分组继续进行计算,而不是重新过滤出这个组的数据。
4. 缺省情况下,集算器的group函数将使用hash算法对数据分组,但对于已经有序的数据,使用相邻比对的方案会有更高性能,在group函数中使用@o选项可以实现这种分组方案,如:
[email protected](year(OrderDate),SellerId)
对位分组
等值分组的分组依据来自于本数据集的字段,但有时分组依据会来自于外部,比如其他数据集的字段、用户构造的数组、参数列表等,这种分组方式就是对位分组。
与等值分组不同,对位分组可能出现空子集,即没有任何成员与某个分组条目对应。而且还可能出现不完全分组,即有成员不出现在任何分组中。而等值分组是不可能出现这种情况的。
例子描述:已经计算出了绩效成绩前十的销售员列表,请按照该列表的顺序对订单进行分组。
分组前数据集:
订单沿用上一个例子,数据存储于A1中。
绩效成绩前十的销售员,该列表存储于B1中,如下:
销售员列表可以来自于中间表,也可以由一段代码计算生成,它的产生过程不是例子的重点。
集算器代码
[email protected](B1:empID,SellerId)
计算结果
代码解读
- 本例中,分组依据(销售员列表)来自于被分组的数据集之外,分组后每个销售员的数据归为一组,组之间按照分组依据进行排列。
- 订单中的销售员要比列表中的多,这就会导致一部分订单不会出现在任何一个组,如果想把这些订单多分一组,可以使用函数选项@n,如下:
[email protected]@n(B1:empID,SellerId)
多分的一组会排在最后,如下:
3. 有时候分组依据不在被分组的数据集中,比如分组依据是“新上岗的销售员列表”。这种情况下会使结果出现空组,这是正常的。比如把列表中的第一条改为empID=100,计算结果会是这样:
枚举分组
枚举分组的分组依据更加灵活,可以是任意的布尔表达式,符合表达式的记录会归为相同的一组。
与对位分组类似,枚举分组也是不完全分组,可能出现空子集或成员不属于任何分组的情况,而且,枚举分组可能出现成员重复地属于多个分组的情况。
例子描述:将订单分为四组,分别是:A.订单金额小于1000的,B.金额小于2000之间的,C.金额在小于3000的,D.金额小于10000的。特别要求:数据不能重复分组,即如果某个订单已经属于前面的A组,则不能再将它分到后面的B、C、D组。
分组前数据集:
订单沿用上一个例子,数据存储于A1中。
集算器代码
A2=["?<=1000","?<=2000","?<=3000","?<=10000"]
A3=A1.enum(A2,Amount)
计算结果
代码解读:
- 在本例中,分组依据是多个灵活的表达式。每条记录都会和表达式进行匹配,如果符合表达式,这条记录就会成为该组成员。同样的,组之间按照分组依据的顺序进行排列。
- 默认情况下,enum的分组结果是不会产生重复的,即分完A组的数据后,将从剩余的数据中判断是否符合表达B,上述例子就是这种分组方式。如果使用函数选项@r,则表示从全部的数据中判断是否符合表达式B,这就会产生重复的分组结果。比如:[email protected](A2,Amount),计算结果是:
3. 和对位分组类似,如果枚举表达式超出了待分组数据的范围,则该组为空。此外,有些数据不符合任何一个表达式,此时可以用@n函数选项把这些记录归为多余的一组。