SPL 查询与报表计算实战指南 - 6 多层次的关联计算
6 多层次的关联计算
这类任务是指多表关联、两表互关联、自关联等灵活性较高的计算。SQL用JOIN实现关联,碰到多层次关系时,常常要用嵌套结构和递归结构,表被关联多次时还要起别名,代码复杂易出错。
例1:找出Pennsylvania州且部门经理是Texas州的员工
数据源:员工表、部门表(6/Department.txt),两表互相关联。
SPL代码:
A |
B1B |
|
1 |
$select * from Employee.txt |
$select * from 6/Department.txt |
2 |
>A1.switch(Dept,B1:Dept) |
>B1.switch(Manager,A1:EId) |
3 |
=A1.select(State=="Pennsylvania" && Dept.Manager.State=="Texas") |
A1,B1:加载数据。
A2:将员工表的Dept字段切换为部门表的记录引用。函数switch可以将员工表的部门字段切换为部门表对应的记录。
l 知识:函数switch
SPL有个switch函数,可以将字段值切换为外键表(字典表、维表)的记录引用(指引、指针),从而建立两表的关联关系。这样就可以免去关联语句或复用关联关系,直接用对象的方式(点号)访问外键表的字段,形式上更加直观,可以显著降低灵活关联的复杂度。
参数 foreign:被替换的字段,经常是事实表的外键。
参数 D:外键表(字典表、维表)。可以通过建立主键加快切换速度。
参数 key:D 中的字段,通常是主键,用来替换 foreign。
B2:将部门表的 Manager 字段切换为员工表的记录引用。
A3:筛选员工,条件是所在洲为Pennsylvania且部门经理所在州是Texas。Dept.Manager.State表示当前员工的部门经理所在的州,通过点号表达了3层关联关系,从员工表到部门表再回到员工表。
例2:每个订单及其所有下级订单的总金额
数据源:订单表(6\OrdersWithParent.txt)的ParentID字段指向本订单的上级订单,相对的,本订单称作下级订单,通过ParentID和ID可以建立树状的自关联结构。
SPL代码:
A |
|
1 |
$select OrderID,ParentID,Amount from 6\OrdersWithParent.txt |
2 |
=A1.switch(ParentID,A1:OrderID) |
3 |
=A1.new(OrderID,A1.nodes(ParentID,~).sum(Amount)+Amount:Total) |
A1:加载数据。
A2:将 ParentID 字段切换为本表的 ID 字段,建立自关联关系。其中 OrderID==9 的订单及多级的下级订单如图。
A3=A1.new(OrderID,A1.nodes(ParentID,~)…) 根据A1新建二维表,先计算出当前订单的所有下级订单,~表示A1的当前记录。OrderID==9的订单的多级的下级订单如图。A1.nodes(ParentID,~)可以从A1里计算出~的所有下级订单。
l 知识点:函数nodes
SPL有个nodes函数,可以基于switch函数预先建立的自关联序表,计算出指定记录的所有下级记录。这样可以避免手工实现递归结构,显著降低代码难度。
参数F:上级节点的字段名。
参数r:指定的记录,可以通过序表.select@1或序表(序号)等形式计算得出。为了防止递归层数过深,nodes函数另有参数可以指定最大递归深度,缺省值1000。
A3=A1.new(...sum(Amount)+Amount:Total) 再对当前订单的所有下级订单的金额求和,并加上当前订单的金额。
扩展阅读
(https://c.raqsoft.com.cn/article/1745399064011)
(https://c.raqsoft.com.cn/article/1693349108072)
(https://c.raqsoft.com.cn/article/1735607423435)