SPL:静态转置
转置功能常用报表等前端展现,将查询出来的数据转置成指定的显示格式。比如行转列,列转行,以及比较复杂的动态转置等等。其中静态转置是指,转置后的表结构事先可以确定,目标结构不会根据数据进行动态的变化。
1. 行转列
行转列顾名思义,这个功能是实现行与列的转换,也就是将行中的值作为列名。行转列的实际应用,基本都要跟随在分组聚合运算之后,通过分组把用于转置的列中每一行数据都处理成不重复的值后,再将各行的值作为列名来展开。行转列的作用,其实就是将某一列的聚合结果,细分为多个更具体的列的聚合结果,以达到更直观的视觉效果。
【例 1】 根据学生成绩表,统计每个班的各科最高分,按列显示。部分数据如下:
CLASS | STUDENTID | SUBJECT | SCORE |
1 | 1 | English | 84 |
1 | 1 | Math | 77 |
1 | 1 | PE | 69 |
1 | 2 | English | 81 |
1 | 2 | Math | 80 |
… | … | … | … |
期望得到如下格式结果:
CLASS | MAX_MATH | MAX_ENGLISH | MAX_PE |
1 | 97 | 96 | 97 |
2 | 97 | 96 | 97 |
… | … | … | … |
在 SPL 中提供了函数 A.pivot() 用于行列转置,默认为行转列。
SPL脚本如下:
A | |
1 | =T("Scores.csv") |
2 | =A1.groups(CLASS,SUBJECT;max(SCORE):MAX_SCORE) |
3 | =A2.pivot(CLASS;SUBJECT,MAX_SCORE;"Math":"MAX_MATH","English":"MAX_ENGLISH","PE":"MAX_PE") |
A1:从文件中导入学生成绩表。
A2:分组汇总每班各科的最高分。
A3:使用函数 A.pivot(),将每班各科最高分行转列。
2. 列转行
列转行与行转列相反,每一个要转置的字段都生成新的一行,字段名或对应名称转化为新字段的值,原字段值则转为另一新字段的值。
【例 2】根据奥运会奖牌总榜,生成每种奖牌的榜单。部分数据如下:
Game | Nation | Gold | Silver | Copper |
30 | USA | 46 | 29 | 29 |
30 | China | 38 | 27 | 23 |
30 | UK | 29 | 17 | 19 |
30 | Russia | 24 | 26 | 32 |
30 | Korea | 13 | 8 | 7 |
… | … | … | … | … |
期望得到如下格式结果:
GAME | NATION | MEDAL_TYPE | MEDALS |
30 | USA | GOLD | 46 |
30 | USA | SILVER | 29 |
30 | USA | COPPER | 29 |
30 | China | GOLD | 38 |
30 | China | SILVER | 27 |
30 | China | COPPER | 23 |
… | … | … | … |
在 SPL 中函数 A.pivot() 选项 @r 时用于列转行。
SPL脚本如下:
A | |
1 | =T("Olympic.txt") |
2 | =A1.pivot@r(GAME,NATION;MEDAL_TYPE,MEDALS; GOLD, SILVER, COPPER) |
A1:导入奥运会奖牌表。
A2:使用函数 A.pivot@r(),将字段 GOLD、SILVER、COPPER 进行列转行。
3. 行列互转
有些时候,我们需要将行中的值作为列名,并且将列名转换为字段值。
【例 3】 按渠道分类的销售表,按年月进行记录。部分数据如下:
YEAR | MONTH | ONLINE | STORE |
2020 | 1 | 2440 | 3746.2 |
2020 | 2 | 1863.4 | 448.0 |
2020 | 3 | 1813.0 | 624.8 |
2020 | 4 | 670.8 | 2464.8 |
2020 | 5 | 3730.0 | 724.5 |
… | … | … | … |
期望查询 2020 年每种渠道每个月的销售额,格式如下:
CATEGORY | 1 | 2 | 3 | … |
ONLINE | 2440 | 1863.4 | 1813.0 | … |
STORE | 3746.2 | 448.0 | 624.8 | … |
按照逻辑顺序,先使用函数 A.pivot@r()列转行,再使用函数 A.pivot() 行转列即可。
SPL脚本如下:
A | |
1 | =T("MonthSales.csv").select(YEAR:2020) |
2 | =A1.pivot@r(YEAR,MONTH; CATEGORY, AMOUNT) |
3 | =A2.pivot(CATEGORY; MONTH, AMOUNT) |
A1:导入销售表,并选出 2020 年的记录。
A2:使用函数 A.pivot@r() 列转行,将渠道类型转换为 CATEGORY 的字段值。列转行后结果如下:
YEAR | MONTH | CATEGORY | AMOUNT |
2020 | 1 | ONLINE | 2440 |
2020 | 1 | STORE | 3746.2 |
2020 | 2 | ONLINE | 1863.4 |
2020 | 2 | STORE | 448.0 |
2020 | 3 | ONLINE | 1813.0 |
2020 | 3 | STORE | 624.8 |
… | … | … | … |
A3:使用函数 A.pivot() 行转列,将月份字段的值转换为列。
英文版