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