SQL中with recursive用法案例详解

SQL提供了递归查询,可将当前查询结果作为下一次的查询集合进行再次查询,最后得到我们想要的结果。
关键字 with recursive

准备

假设我们有一张机构表org,如下:

列名描述
id机构ID
pid上级机构ID
name机构名称

查询当前机构和它的所有下级,以列表形式显示

with recursive cte as
(
	select pc1.* from org pc1 where pc1.id in ('000000')
	union all
	select pc2.* from org pc2 inner join cte c on c.id=pc2.pid
)

select ct.* from cte ct;

从上到下,以链路形式追加

如获取某个机构ID和它所有的下级,且以链路的形式显示
机构ID: a>b>c>d
机构名称:机构1>机构2>机构3>机构4

with recursive cte as
(
	select pc1.id,
	cast(pc1.id as varchar(500)) as id_seq,
	cast(pc1.name as varchar(500)) as name_seq, 
	from org pc1 where pc1.id in ('000000')

	union all
	
	select pc2.id,
	cast(c.id_seq || '>' || pc2.id  as varchar(500)) as id_seq,
	cast(c.name_seq || '>' || pc2.name   as varchar(500)) as name_seq, 
	from org pc2 inner join cte c on c.id=pc2.pid
)

select ct.* from cte ct;

从下到上 获取链路

如获取某个机构ID和它的所有上级,且以链路的形式显示

with recursive cte as
(
	select 
	pc1.id,
	pc1.pid,
	cast(pc1.id as varchar(500)) as id_seq,
	cast(pc1.name as varchar(500)) as name_seq, 
	from org pc1 where pc1.id in ('66666')

	union all
	
	select 
	pc2.id,
	pc2.pid,
	cast(pc2.id || '>' || c.id_seq  as varchar(500)) as id_seq,
	cast(pc2.name || '>' || c.name_seq   as varchar(500)) as name_seq, 
	from org pc2 inner join cte c on c.pid=pc2.id
)

select ct.* from cte ct;

彩蛋

利用with recursive实现斐波那契数列

方法1

with recursive fibonacci as
(
	select 1 as n, 0 as fib_n,1 as next_fib_n

	union all
	
	select n+1, next_fib_n, fib_n+next_fib_n from fibonacci where n < 40
)

select * from fibonacci;

方法2

with recursive fibonacci(n,fib_n,next_fib_n) as
(
	select 1, 0 ,1

	union all
	
	select n+1, next_fib_n, fib_n+next_fib_n from fibonacci where n < 40
)

select * from fibonacci;
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
WITH RECURSIVESQL Server递归查询的一种方式,也称为CTE递归查询。递归查询是指在一个表对自身进行查询,直到查询结果满足条件为止。在SQL Server使用WITH RECURSIVE可以实现递归查询。WITH RECURSIVE的语法如下: ``` WITH recursive_cte (col1, col2, col3, ...) AS ( --初始查询语句 SELECT col1, col2, col3, ... FROM table_name WHERE condition UNION ALL --递归查询语句 SELECT col1, col2, col3, ... FROM table_name JOIN recursive_cte ON recursive_cte.col = table_name.col WHERE condition ) SELECT * FROM recursive_cte; ``` 其,recursive_cte是递归公共表达式的名称,col1、col2、col3是要查询的列,table_name是要查询的表名,condition是查询条件。在WITH RECURSIVE,包含两个查询语句:初始查询语句和递归查询语句。初始查询语句用于筛选出符合条件的记录,递归查询语句用于在初始查询语句的基础上对自身进行递归查询。 需要注意的是,WITH RECURSIVE的递归查询语句必须包含UNION ALL关键字,并且UNION ALL后面的SELECT语句必须引用了递归公共表达式recursive_cte。如果不包含UNION ALL或者引用了其他表,则会导致死循环。 以下是一个WITH RECURSIVE的例子: ``` WITH recursive_cte (employee_id, manager_id, level) AS ( -- 初始查询语句 SELECT employee_id, manager_id, 0 as level FROM employee_table WHERE employee_id = 1 UNION ALL -- 递归查询语句 SELECT employee_table.employee_id, employee_table.manager_id, recursive_cte.level + 1 FROM employee_table JOIN recursive_cte ON recursive_cte.manager_id = employee_table.employee_id ) SELECT * FROM recursive_cte; ``` 这个例子用于查询一个员工及其直接或间接的所有上级领导。在初始查询语句,我们选择了员工ID为1的员工作为起点。在递归查询语句,我们通过JOIN连接到employee_table表,并使用recursive_cte的level来计算每个员工的级别。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值