SQL中with recursive XXX as

 

首先有上述这个城市级别组织结构,根据这个结构定义表和插入数据。

create table city_info(
	id int primary key auto_increment,
	name varchar(52),
	p_id int
);

insert into city_info(id,name,p_id) values
(1,'中国',-1),(2,'江苏省',1)
,(3,'南京市',2),(4,'六合区',3),(5,'高淳区',3)
,(6,'溧水区',3),(7,'江宁区',3),(8,'徐州市',2);

表数据如下,

with recursive XXX as 这是一个用来执行递归的SQL查询,他会把查询出来的结果再次代入到查询子句中继续查询。

如下模板所示,as里面是一个子查询,子查询不断递归返回数据,然后数据统一由select id from alias_table_name返回。

SELECT id,name,p_id FROM `city_info` where id in (
	with recursive alias_table_name as (子查询)
	select id from alias_table_name
)

子查询里面是这样的:
    初始条件;
    union all
    循环查询条件;

现在定一个目标,查询南京市,及所有他的附属区域(即子节点)。

所以定义初始条件就是查询南京市,

初始条件: select a.id from city_info a where a.id = 3

循环条件就是 p_id =  id, 这种,

循环查询条件:select b.id from city_info b,alias_table_name 
where b.p_id = alias_table_name.id

所以上述用with recursive XXX as 这个语句组合起来就是,

SELECT id,name,p_id FROM  city_info  where id in (
	with recursive alias_table_name as (
			select a.id from city_info a where a.id = 3
			union all
			select b.id from city_info b,alias_table_name where b.p_id = alias_table_name.id
	)
	select id from alias_table_name
)

执行结果如下,

 分析递归行为,

第一次执行递归: id=3的数据,赋值给表alias_table_name
第二次执行递归: b.p_id = 3的数据,赋值给表alias_table_name
第三次执行递归: b.p_id = 4,5,6,7的数据,此时为空,返回递归

这样就查询出 id=3,4,5,6,7的数据。

PS: 我用MySQL5.X.X 版本是报语法错误,换成mysql.8就好了。

还有一个是with XXX as ,这个是把查询当做子查询,并有一个别名XXX,并没有递归,同时数据库会对该子句生成临时表;

如下案列所示,

SELECT id,name,p_id FROM  city_info  where id in (
	with alias_table_name as (
			select a.id from city_info a where a.id = 3
-- 			union all
-- 			select a.id from city_info a where a.id = 4
	)
	select id from alias_table_name
)

SELECT id,name,p_id FROM  city_info  where id in (
	with alias_table_name as (
			select a.id from city_info a where a.id = 3
 			union all
 			select a.id from city_info a where a.id = 4
	)
	select id from alias_table_name
)

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、付费专栏及课程。

余额充值