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:生成由序号、行政区名称和上级行政区名称组成的表。

Organization.txt

ChinaRegion.csv