递归

阅读(26) 标签: 递归,

功能:

在树形结构的表里,从某些行出发,沿着上级或下级的关系,一层一层地找出相关的记录。

语法:

递归 [方向] 起始 <起始条件式> 选出列 {<计算式> [命名 <新列名>]} [层次 <层次列名>] [主键 <主键字段>] [父列 <父列字段>] [条件 <条件式>]

规则:

这里的"树形结构"是指,表里有两个字段,一个字段能唯一区分每一行(比如员工编号),另一个字段记录"这一行的上级是哪一行"(比如上级编号);这两个字段就把整个表组织成了一棵树,最上面那一行没有上级,是树的根。

本功能相当于SQL里的递归子查询(WITH RECURSIVE),并在此基础上做了归纳和扩展:参数起始相当于SQL里最先查出的那部分行,参数方向、父列、主键决定后面怎么一层层地找下去,参数层次相当于递归的层数。

下面将使用员工表作为焦点表来介绍递归功能,员工表的主键为员工编号,表数据内容如下:

员工编号

姓名

上级编号

推荐人编号

部门

工资

E01

张伟

 

 

总经理室

30000

E02

李娜

E01

E01

销售部

15000

E03

王强

E01

E02

技术部

18000

E04

赵敏

E02

E03

销售部

9000

E05

刘洋

E02

E03

销售部

8000

E06

陈静

E03

E01

技术部

12000

E07

杨帆

E03

E06

技术部

7000

E08

周涛

E04

E07

销售部

5000

说明:该表可以看做两个树形结构,按上级编号看,这棵树是:张伟下面有李娜、王强;李娜下面有赵敏、刘洋;王强下面有陈静、杨帆;赵敏下面是周涛。按推荐人编号看,是另一棵树:张伟推荐了李娜、陈静;李娜推荐了王强;王强推荐了赵敏、刘洋;陈静推荐了杨帆;杨帆推荐了周涛。张伟既没有上级、也没有推荐人,所以他是两棵树的根。

参数:方向

查找的方向。

必填,省略参数名。枚举类型,枚举值:

- 向上:从起始行出发找上级,也就是沿着参数父列一直往根的方向找。

- 向下:从起始行出发找下级,也就是沿着参数父列一直往叶子的方向找。

  示例:

递归 向上 起始 (姓名="赵敏") 选出列 姓名 父列 上级编号  //从赵敏出发,向上找出她的所有上级,结果如下:

姓名

赵敏

李娜

张伟

解释:赵敏是起始行(第1层);她的上级是李娜(第2层);李娜的上级是张伟(第3层);张伟没有上级,就不再有下一层了。结果里行的先后顺序,就是一层一层找上来的顺序。

递归 向下 起始 (上级编号 为空) 选出列 姓名 父列 上级编号  //从张伟出发,向下找出他的所有下级,结果如下:

姓名

张伟

李娜

王强

赵敏

刘洋

陈静

杨帆

周涛

解释:张伟是第1层,李娜和王强是第2层,赵敏、刘洋、陈静、杨帆是第3层,周涛是第4层。同一层的记录排在一起,同一层里按焦点表原来的顺序排列。

参数:起始

将满足条件的行作为起点,起点本身是第一层,可一行或多行。

必填,不可省略参数名。

  示例:

递归 向下 起始 (姓名="李娜") 选出列 姓名 父列 上级编号  //从李娜开始,向下找出她和她的所有下级,结果如下:

姓名

李娜

赵敏

刘洋

周涛

解释:起点是李娜,不是根,所以结果里没有张伟、王强、陈静、杨帆,他们不在李娜下面。

递归 向上 起始 (部门="技术部") 选出列 姓名 父列 上级编号  //技术部有三个人(王强、陈静、杨帆),从他们三个一起出发向上找各自的上级,结果如下:

姓名

王强

张伟

陈静

王强

张伟

杨帆

王强

张伟

解释:条件"部门='技术部'"同时选中3行(王强、陈静、杨帆),这3行都是起点,都是第1层;再往上找一层,他们的上级都是张伟,张伟是第2层。多行起点时,每个起点依次带出自己到根的整条链:王强的上级是张伟;陈静的上级是王强、王强的上级是张伟;杨帆的上级是王强、王强的上级是张伟。本功能不再去掉重复的行,所以王强出现3次(1次起点、2次上级)、张伟出现3次(都是上级)。

参数:选出列  <计算式> [命名 <新列名>]

指定结果里要哪些列。

必填,不可省略参数名,复合参数,由计算式+命名组成,多组表示选出多个列,多组之间用逗号分隔。

  示例:

递归 向下 起始 (上级编号 为空) 选出列 姓名, 部门, 工资 父列 上级编号  //从张伟出发向下找出全部记录,结果里要姓名、部门、工资三个列,结果如下:

姓名

部门

工资

张伟

总经理室

30000

李娜

销售部

15000

王强

技术部

18000

赵敏

销售部

9000

刘洋

销售部

8000

陈静

技术部

12000

杨帆

技术部

7000

周涛

销售部

5000

解释:结果里列的先后顺序,就是你写"选出列"的先后顺序。

  计算式:

子参数计算式是参数选出列里每一组的计算式。可以直接是列名或表达式。

必填,省略参数名。本参数不支持跨行计算和聚合计算。

  示例:

  递归 向上 起始 (姓名="赵敏") 选出列 姓名,工资*1.1 父列 上级编号  // 从赵敏出发向上找出她的所有上级,用计算式"工资*1.1"算出调整后工资,结果如下:

姓名

工资*1.1

赵敏

9900.0

李娜

16500.0

张伟

33000.0

命名:

子参数命名是参数选出列里每一组的列名,省略时沿用原列名,计算式非单列时自动用计算式当列名。

可选,不可省略参数名。注意,本参数要和计算式搭配使用。

  示例:

递归 向上 起始 (姓名="赵敏") 选出列 姓名 命名 员工 部门 工资*1.1 命名 调整后工资 父列 上级编号  //从赵敏出发向上找出她的所有上级,用计算式"工资*1.1"计算出结果后列命名为【调整后工资】 ,姓名列命名为【员工】,结果如下:

员工

调整后工资

赵敏

9900.0

李娜

16500.0

张伟

33000.0

参数:层次

给结果中增加层次列,列值为层次号,起始行为第1层,每往下一层加1。

可选,不可省略参数名。

示例:

递归 向下 起始 (上级编号 为空) 选出列 姓名 层次 层级 父列 上级编号  //从张伟出发向下找出全部记录,并且要一个层次号列,列名叫"层级",结果如下:

姓名

层级

张伟

1

李娜

2

王强

2

赵敏

3

刘洋

3

陈静

3

杨帆

3

周涛

4

  递归 向上 起始 (姓名="赵敏") 选出列 姓名 层次 层级 父列 上级编号  // 从赵敏出发向上找出她的所有上级,并且要一个层次号列,列名叫"层级",结果如下:

  姓名

层级

赵敏

1

李娜

2

张伟

3

解释:不管向上还是向下,起始行都是第1层,往上或往下每一层加1。

参数:主键

能唯一区分每一行的字段,用于判断是否已经找过。

可选,不可省略参数名。省略时用表的主键。

注意,本参数只是内部用来认行的,不会出现在结果里,结果里有哪些列由参数选出列决定。

示例:

递归 向下 起始 (上级编号 为空) 选出列 姓名 层次 层级 主键 员工编号 父列 上级编号  // 从张伟出发向下找出全部记录,并且写出主键是员工编号,结果如下:

姓名

层级

张伟

1

李娜

2

王强

2

赵敏

3

刘洋

3

陈静

3

杨帆

3

周涛

4

由于员工表中主键为员工编号,所以上面递归语句中”主键 员工编号”可以省略。

参数:父列

记录"这一行的上级是谁"的字段,不同父列会得到不同的树形结构。

必填,不可省略参数名。

示例:

递归 向上 起始 (姓名="赵敏") 选出列 姓名, 部门 父列 上级编号  // 按上级编号这棵树,从赵敏出发向上找出她的所有上级,结果如下:

姓名

部门

赵敏

销售部

李娜

销售部

张伟

总经理室

递归 向下 起始 (推荐人编号 为空) 选出列 姓名, 部门 父列 推荐人编号  //换成推荐人编号这棵树,从张伟出发向下找出全部记录,结果与上例不同,结果如下:

姓名

部门

张伟

总经理室

李娜

销售部

王强

技术部

赵敏

销售部

刘洋

销售部

陈静

技术部

杨帆

技术部

周涛

销售部

解释:按推荐关系,张伟推荐了李娜、陈静;李娜推荐了王强;王强推荐了赵敏、刘洋;陈静推荐了杨帆;杨帆推荐了周涛。这棵树和按上级编号看的那棵树不一样,所以结果也不一样。

参数:条件

对起始行之外的结果做额外的筛选,只保留满足这个条件的行。起始行不满足条件不会影响继续往下一层找。

可选,不可省略参数名。
 
示例:

  递归 向下 起始 (上级编号 为空) 选出列 姓名, 工资 条件 (工资>=8000) 父列 上级编号  //从张伟出发向下找出全部记录,结果里只要工资不低于8000的,结果如下:

姓名

工资

张伟

30000

李娜

15000

王强

18000

赵敏

9000

刘洋

8000

陈静

12000

递归 向下 起始 (上级编号 为空) 选出列 姓名, 部门 条件 (部门="销售部") 父列 上级编号  //从张伟出发向下找出全部记录,结果里只要销售部的,结果如下:

姓名

部门

张伟

总经理室

李娜

销售部

赵敏

销售部

刘洋

销售部

周涛

销售部

解释:张伟是总经理室,不满足"销售部"这个条件,但他是起始行,所以仍保留在结果里;他的下级李娜、王强照常往下找,所以李娜这一支的记录仍然出现在结果里。这说明参数条件只筛除起始行之外的记录,不影响往下找。