🍬上节我们讲了SPL如何连接MySQL及它们是如何结合一起实现基本的CRUD的,最后讲了常见的SQL 语句与集算器语法的对照。
这一节我们来讲一下:SPL中常规 SQL 式运算。其中有一部分上节有讲过(过滤等),可以自行跳过。在SPL中,从数据源将数据读成序表以后,就可以进行所有SQL式的运算,如过滤、汇总、跨列计算、排序、分组汇总、分组过滤、Top-N、分组Top-N、去重、分组去重、关联查询等。
官方给的例子是以文件数据源(txt,xlsx)举例,这里我以**「MySQL」**作为数据源来演示,思维导图如下。
❝
🎁数据库脚本gzh(亦知码)回复SPL学习笔记(二)「领取~」另:「连接数据库步骤在上一SPL学习笔记(一)中有演示,这里贴个图」
❞
1.过滤
示例:从学生成绩表Students_scores中筛选出班号(class)为1班中学生成绩。
=spltest1.query("select * from students_scores").select(class==1)
得到的结果为
2.汇总
示例:现在我想计算一班学生成绩表中学生的语文平均分、数学最高分、英语总分。
❝
🍭说明:
A1 读取表中数据,
A2 计算语文平均分。
A3 计算数学最高分。
A4 计算英语总分
❞
=spltest1.query("select * from students_scores").select(class==1)
=A1.avg(Chinese)
=A1.max(Math)
=A1.sum(English)
3. 跨列计算
示例:如果我想计算一班学生成绩表中每位学生的总分。
说明:
- A5 在结果后面新增一列total_score,其值为英语、语文、数学3列之和。
=A1.derive(English+Chinese+Math:total_score)
4. 排序
示例:我们将各班学生成绩表按照班号升序、总分升序的顺序排列。
🍭说明:
-
C9 按班级号升序排列。
-
D9 先按班级号升序排列,班级内再按数学成绩升序排列。
=A9.sort(class)
=A9.sort(class,Math)
5.分组汇总
示例:查询一班的英语最低分、语文最高分、数学总分。
❝
🍭说明:
- A8 按班级分组,计算各班英语最低分、语文最高分、数学总分。
❞
=A1.groups(class;min(English),max(Chinese),sum(Math))
6.分组后过滤
示例:找出英语平均分低于70分的班级。
❝
🍭说明:
A9 查询全部学生的成绩。
A10 按班级分组,计算各班英语平均分命名新列名为avg_En。
A11 从A2中选出英语平均分低于70的班级。
❞
=spltest1.query("select * from students_scores")
=A9.groups(class;avg(English):avg_En)
=A10.select(avg_En<70)
7. 分组Top-N
示例:查看一班英语成绩最**「高」的「3个同学成绩」**。
❝
🍭说明:
- A13 按班级分组,各组英语升序排列后,取出前3个最低的英语成绩。
❞
=A1.top(-3;English)
8. 分组Top-N
示例:查看各班英语成绩**「最低的3个同学」的「英语成绩」**。
❝
🍭说明:
- A12 按班级分组,各组英语升序排列后,取出前3个最低的英语成绩。
❞
=A1.groups(class;top(3,English))
9. 去重
示例:查询所有班级编号。
❝
🍭说明:
- A14 查出所有不重复的班级编号。
❞
=A9.id(class)
10. 去重计数
示例:查询共有多少个班级编号。
❝
🍭说明:
- A15 查出所有不重复的班级编号的个数。
❞
=A9.icount(class)
11.分组去重计数
示例:产品销售记录文件sales.txt如下图,查询每个产品有销售记录的天数。
❝
🍭说明:
A16 查询每个商品出售的日期
A17 按产品编号pid分组,统计本组不同日期个数命名为 days。
❞
=spltest1.query("select * from sales")
=A16.groups(pid;icount(date):days)
12. 外键关联
❝
🎯什么是外键关联?答:两个数据表,表A中的某些字段与表B的**「主键」关联,「B称为A的外键表」,称此关联为「外键关联」**。
❞
示例:销售订单信息和产品信息分别存储在sales和product中,如下图
接下来我们计算各订单的销售额。
❝
🍭说明:
A16 读取销售订单数据。
A18 读取产品信息数据。
A19 用switch函数将A1中id与A2中的id进行关联(id为主键时也可省略不写),此时pid列转换成了指向与它对应的产品记录,如下图所示。
A20 A3中新增一列amount,其值为销售数量quantity与产品价格Price的积,表达式ProductID.Price表示pid列指向的记录的Price列值。
❞
=spltest1.query("select * from sales")
=A16.groups(pid;icount(date):days)
=spltest1.query("select * from product")
=A16.switch(pid,A18:id)
=A19.derive(quantity*pid.price:amount)
❝
🎃注意:
- 对于多个外键字段关联的情况,就不能用switch函数了。只能用join函数来关联。
❞
下面给出join格式:
=A1.join([A1的主键]:[A?的外键],A?)
//这里贴出switch对比
=A1.switch([A1的主键],A?:[外键字段])
13. 主键关联
❝
🎯什么是主键关联? 答:表A的主键与表B的**「主键关联」,A和B相互称为「同维表」。「同维表」是「一对一」的关系,「逻辑上可以简单地看成一个表来对待」。「同维表都是按主键关联」,「相应记录是唯一对应的。」**
❞
示例:我们想计算各订单的销售额(订单和商品一对一)。理论上应该于12的结果一样 。
❝
🍭说明:
A16 读取销售订单数据。
A18 读取产品信息数据。
A21 用join函数将A1中id与A2中的id进行关联(id为主键时也可省略不写),此时pid列转换成了指向与它对应的产品记录。
A22 中新增一列amount,其值为销售数量quantity与产品价格price的积,表达式pid.price表示pid列指向的记录的Price列值。
❞
=join(A18:product,id;A16:sales,pid)
=A21.new(product.id,product.name,product.price,sales.quantity*product.price:amount)
❝
🎃注意:
- 这里有个坑,12中的switch函数后不能直接使用join函数,需要将switch搬到它,不然会爆错误后面去如下图:
❞
「另:还有一种主子表形式的主键关联。表A的主键与表B的部分主键关联,A称为主表,B称为子表。这种写法基本不变,不过要注意,主子表与同维表不同的是,主子表是一对多的关系。」