SPL:取最大值 / 组内最大值所在记录

有些时候,我们并不关心最大值具体是多少,而是关心最大值所在记录。比如查询数学成绩最高的学生 ID, 选出每个月销售额最高的订单信息等等。

1. 取最大值所在记录

取最大值所在记录,需要找到最大值出现在哪些行上(有多个最大值时可能是多行),再返回对应的记录。SPL 提供了函数 A.maxp() 用于选出最大值所在记录。

【例 1】 根据成绩表,求一班数学成绩最高的学生 ID。部分数据如下:

CLASS

STUDENTID

SUBJECT

SCORE

1

1

English

84

1

1

Math

77

1

1

PE

69

1

2

English

81

1

2

Math

80

 

SPL 脚本如下:


A

1

=T("Scores.csv").select(SUBJECT=="Math"&&CLASS==1)

2

=A1.maxp(SCORE).STUDENTID

A1:导入成绩表,并查询一班的数学成绩。

A2:使用了函数 A.maxp() 选出最高分所在的记录,再从记录中取学生 ID。

最大值所在记录不一定是唯一的,如果想返回所有最高分记录,可以使用函数A.maxp()的选项@a


A

2

=A1.maxp@a(SCORE).(STUDENTID)

A2:使用 A.maxp() 函数的 @a 选项,选出所有最高分的记录,然后取出所有学生 ID。

其中 A1.maxp@a(SCORE) 的执行结果如下:

CLASS

STUDENTID

SUBJECT

SCORE

1

10

Math

97

1

13

Math

97

    可以看到一班的数学最高分有两位同学,他们的学号分别是 10 和 13。

    类似的,SPL 也提供了函数 A.minp(),用于取最小值所在记录。如果想取所有最小值所在记录,函数 A.minp() 也支持选项 @a。

 

2. 取组内最大值所在记录

通常人们对分组后的聚合值更感兴趣,因此分组运算常常伴随着对子集的进一步汇总计算。通过分组汇总,我们可以很方便的计算每组的最大值或最小值。但是,我们仍然有对这些分组子集而不是聚合值更感兴趣的时候。比如说,我们想要知道每个月单笔销售额最高的销售记录中,客户名称、销售人员等信息,而不在意最高的销售额具体是多少。

SPL提供了函数 group(),我们可以用它来实现真正的分组,分组后的结果集是由多个分组子集组成的集合。这就使得 group 函数可以支持,在每个分组子集中取最大值所在记录这样的运算。我们通过一个简单的例子来看一下,如何取组内最大值所在记录。

【例 2】 根据销售表,取出 2014 年每个月销售额最高的销售记录。部分数据如下:

ID

CUSTOMERID

ORDERDATE

SELLERID

AMOUNT

10400

EASTC

2014/01/01

1

3063.0

10401

HANAR

2014/01/01

1

3868.6

10402

ERNSH

2014/01/02

8

2713.5

10403

ERNSH

2014/01/03

4

1005.9

10404

MAGAA

2014/01/03

2

1675.0

 

    我们首先选出 2014 年的销售记录,将销售记录按照月份进行分组,并从每个月份的销售记录中选出销售额最大的记录,最后将这些选出的记录合并在一起。

SPL脚本如下:


A

1

=T("Sales.csv").select(year(ORDERDATE)==2014)

2

=A1.group(month(ORDERDATE);~.maxp@a(AMOUNT):MAX_AMOUNT)

3

=A2.conj(MAX_AMOUNT)

A1:导入销售表,并选出 2014 年的销售数据。

A2:使用函数 A.group() 将销售记录按照月份进行分组,并选出每个分组子集中销售额最大的记录。

A3:将所有月份的最大值记录合并。

Sales.csv

Scores.csv