postgresql的with和resursive的使用
- 操作系统:win 10
- 数据库系统: PostgreSQL 12.3
说明:遇到树形结构的时候,postgresql中with配合recursive可以实现遍历。
创建测试数据:
create table digui_test(id int , pid int , name varchar(10));
insert into digui_test values(2 , 0 , 'a');
insert into digui_test values(1 , 0 , 'b');
insert into digui_test values(3 , 2 , 'c');
insert into digui_test values(4 , 2 , 'd') ;
insert into digui_test values(5 , 2 , 'e');
insert into digui_test values(6 , 2 , 'f') ;
insert into digui_test values(7 , 3 , 'g');
insert into digui_test values(8 , 3 , 'h') ;
insert into digui_test values(9 , 4 , 'i');
insert into digui_test values(10 , 5 , 'j') ;
insert into digui_test values(11 , 7 , 'k');
insert into digui_test values(12 , 2 , 'l') ;
insert into digui_test values(13 , 9 , 'm');
insert into digui_test values(14 , 9 , 'n') ;
insert into digui_test values(15 , 4 , 'o');
suqinghua=# select * from digui_test ;
id | pid | name
----+-----+------
2 | 0 | a
1 | 0 | b
3 | 2 | c
4 | 2 | d
5 | 2 | e
6 | 2 | f
7 | 3 | g
8 | 3 | h
9 | 4 | i
10 | 5 | j
11 | 7 | k
12 | 2 | l
13 | 9 | m
14 | 9 | n
15 | 4 | o
(15 rows)
实验:
黑出一个数据id号,求出其下所有节点的信息
假设给出的id为 3:
suqinghua=#
with recursive t as (select * from digui_test where id=3
union all
select k.id,k.pid,k.name from digui_test k,t c where c.id=k.pid)
select * from t;
id | pid | name
----+-----+------
3 | 2 | c
7 | 3 | g
8 | 3 | h
11 | 7 | k
(4 rows)
注:
通过我的理解,我觉的union all 后面一部分关于调用t,不是递归调用(我搜索到其他的博客有谈到rescursive是递归的标志),因为这段语句没有递归的出口,递到什么时候才可以归,所以我认为是union all后面一部分首先调用了第一次进入with语句时‘select * from digui_test where id=3 ’查询出的第一条结果,然后根据第一条结果执行‘select k.id,k.name,k.pid from digui_test k , t c where c.id = k.pid’使with的结果变为三条数据‘ 3 | 2 | c , 7 | 3 | g, 8 | 3 | h’,最后‘select k.id,k.name,k.pid from digui_test k , t c where c.id = k.pid’遍历三条结果,变为四条结果,在遍历没有扫描到新的数据,遍历结束。
(我的理解肯定有偏差或者错误,恳请各位大佬评论指正,感激不尽)。