操作系统:windows 10 家庭中文版
数据库系统: PostgreSQL 9.6.2
遇到树形结构的数据时,oracle可以使用层次化查询connect by遍历表数据,而在postgreSQL数据库中,我们使用RECURSIVE参数配合with查询来实现遍历。
创建测试数据:
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');
test=# 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 行记录)
假设给出id为3:
test=# with RECURSIVE t as
test-# (
test(# select a.id,a.name,a.pid from digui_test a where id=3
test(# union all
test(# select k.id,k.name,k.pid from digui_test k , t c where c.id = k.pid
test(# )
test-# select id,name,pid from t;
id | name | pid
----+------+-----
3 | c | 2
7 | g | 3
8 | h | 3
11 | k | 7
(4 行记录)
test=# with RECURSIVE t(id,name,pid,depth,path,cycle) as
test-# (
test(# select a.id,a.name,a.pid,1,array[a.id],false from digui_test a where id=3
test(# union all
test(# select k.id,k.name,k.pid,c.depth+1,path||k.id,k.id=any(path) from digui_test k , t c where c.id = k.pid and not cycle
test(# )
test-# select * from t;
id | name | pid | depth | path | cycle
----+------+-----+-------+----------+-------
3 | c | 2 | 1 | {3} | f
7 | g | 3 | 2 | {3,7} | f
8 | h | 3 | 2 | {3,8} | f
11 | k | 7 | 3 | {3,7,11} | f
(4 行记录)
参考:PostgreSQL Online Manuals