SPL:递归查找记录引用
递归运算是指直接或者间接地调用自身的运算方法。比如我们熟悉的汉诺塔问题,就是典型的递归运算。在实际应用中递归查询问题也很常见,比如我们想知道某个部门有哪些上级机构。单纯的查找这个部门的上级机构并不难,但是找到其上级机构以后,还要继续查找其上级机构的上级机构,而且我们并不知道一共要查找多少层从属关系,这时就要用到递归运算了。
1. 递归查找所有引用
【例 1】 根据某公司组织结构表,查询各部门的级别(总部是 1 级,分公司 2 级,依此类推)。部分数据如下:
ID |
ORG_NAME |
PARENT_ID |
1 |
Head Office |
0 |
2 |
Beijing Branch Office |
1 |
3 |
Shanghai Branch Office |
1 |
4 |
Chengdu Branch Office |
1 |
5 |
Beijing R&D Center |
2 |
… |
… |
… |
这个问题需要循环每条记录,递归查找每个机构的所有上级部门。在 SPL 中函数 A.prior(F) 用于递归查找引用,默认查找所有引用。
SPL脚本如下:
A |
|
1 |
=T("Organization.txt") |
2 |
>A1.switch(PARENT_ID,A1:ID) |
3 |
=A1.new(ID,ORG_NAME,~.prior(PARENT_ID).len():LEVEL) |
A1:导入组织机构表。
A2:将父机构 ID 外键对象化,转换为相应的父机构记录,实现自连接。
A3:创建由序号、部门名称和级别构成的新表。其中部门级别,是通过函数 A.prior() 递归查找引用记录的层次数量计算得出。
2. 递归查找引用直到指定值
【例 2】 根据某公司组织结构表,查询北京分公司的下属机构,并列出其上级机构名称,多层的用逗号分隔。部分数据如下:
ID |
ORG_NAME |
PARENT_ID |
1 |
Head Office |
0 |
2 |
Beijing Branch Office |
1 |
3 |
Shanghai Branch Office |
1 |
4 |
Chengdu Branch Office |
1 |
5 |
Beijing R&D Center |
2 |
… |
… |
… |
在这个例子中,我们希望每个机构在递归查找上级机构时,如果查找到指定值(例如北京分公司)则停止递归并保留当前机构,查找不到的机构则过滤掉。在 SPL 中函数 A.prior(F,r) 用于递归查找引用直到指定记录 r。
SPL脚本如下:
A |
|
1 |
=T("Organization.txt") |
2 |
>A1.switch(PARENT_ID,A1:ID) |
3 |
=A1.select@1(ORG_NAME=="Beijing Branch Office") |
4 |
=A1.new(ID,ORG_NAME,~.prior(PARENT_ID,A3) :PARENT_NAME) |
5 |
=A4.select(PARENT_NAME!=null) |
6 |
=A5.run(PARENT_NAME=PARENT_NAME.(PARENT_ID.ORG_NAME).concat@c()) |
A1:导入组织机构表。
A2:将父机构 ID 外键对象化,转换为相应的父机构记录,实现外键对象化。
A3:选出北京分公司的记录。
A4:创建由序号、部门名称和所有上级部门的记录集合组成的表。
A5:选出父机构不为空的记录,即北京分公司的记录。
A6:循环将父机构名称拼成由逗号分隔的字符串。
3. 递归查找叶子记录
【例 3】 在中国行政区划表中,查询河北省下属区县。部分数据如下:
ID |
NAME |
PARENT_ID |
1 |
China |
0 |
11 |
Beijing |
1 |
12 |
Tianjin |
1 |
13 |
Hebei |
1 |
… |
… |
… |
1301 |
Shijiazhuang |
13 |
1302 |
Tangshan |
13 |
… |
… |
… |
与前两个小节相反,本例中是根据父记录查找所有从属的叶子记录。在 SPL 中函数 P.nodes@d(F,r) 用于递归查找所有叶子记录。
SPL脚本如下:
A |
|
1 |
=T("ChinaRegion.csv") |
2 |
>A1.switch(PARENT_ID,A1:ID) |
3 |
=A1.select@1(NAME=="Hebei") |
4 |
=A1.nodes@d(PARENT_ID,A3) |
5 |
=A4.new(ID,NAME,PARENT_ID.NAME:PARENT_NAME) |
A1:导入中国行政区划表
A2:将父行政区 ID 外键对象化,转换为相应的父行政区记录,实现外键对象化。
A3:选出河北省的记录。
A4:使用函数 P.nodes() 进行递归查找,其中选项 @d 时递归查找所有叶子记录。
A5:生成由序号、行政区名称和上级行政区名称组成的表。