PostgreSQL tablefunc详解(兼容oracle connect by)

Oracle connect by语法经常用于有树形关系的记录查询,但是在pg中是不支持这一语法的,不过我们可以使用with recursive语法来实现类似的功能。
除此之外,pg自带的tablefunc插件中的connectby函数也可以达到类似的效果。

使用方法:
connectby(text relname, text keyid_fld, text parent_keyid_fld
[, text orderby_fld ], text start_with, int max_depth
[, text branch_delim ])

参数解释:
在这里插入图片描述

使用举例:
安装插件:

bill@bill=>create extension tablefunc ;
CREATE EXTENSION

建表:

bill@bill=>CREATE TABLE connectby_tree(keyid text, parent_keyid text, pos int);  
CREATE TABLE
bill@bill=>INSERT INTO connectby_tree VALUES('row1',NULL, 0);  
INSERT INTO connectby_tree VALUES('row2','row1', 0);  
INSERT 0 1
bill@bill=>INSERT INTO connectby_tree VALUES('row2','row1', 0);  
INSERT INTO connectby_tree VALUES('row3','row1', 0);  
INSERT 0 1
bill@bill=>INSERT INTO connectby_tree VALUES('row3','row1', 0);  
INSERT 0 1
bill@bill=>INSERT INTO connectby_tree VALUES('row4','row2', 1);  
INSERT 0 1
bill@bill=>INSERT INTO connectby_tree VALUES('row5','row2', 0);  
INSERT INTO connectby_tree VALUES('row6','row4', 0);  
INSERT 0 1
bill@bill=>INSERT INTO connectby_tree VALUES('row6','row4', 0);  
INSERT 0 1
bill@bill=>INSERT INTO connectby_tree VALUES('row7','row3', 0);  
INSERT 0 1
bill@bill=>INSERT INTO connectby_tree VALUES('row8','row6', 0);  
INSERT 0 1
bill@bill=>INSERT INTO connectby_tree VALUES('row9','row5', 0);  
INSERT 0 1

查询:
1、带有分支,但没有orderby_fld (不保证结果的顺序)

bill@bill=>SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0, '~')  
bill-#  AS t(keyid text, parent_keyid text, level int, branch text);
 keyid | parent_keyid | level |       branch        
-------+--------------+-------+---------------------
 row2  |              |     0 | row2
 row4  | row2         |     1 | row2~row4
 row6  | row4         |     2 | row2~row4~row6
 row8  | row6         |     3 | row2~row4~row6~row8
 row5  | row2         |     1 | row2~row5
 row9  | row5         |     2 | row2~row5~row9
(6 rows)

2、没有分支,也没有orderby_fld (不保证结果的顺序)

bill@bill=>SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0)  
bill-#  AS t(keyid text, parent_keyid text, level int); 
 keyid | parent_keyid | level 
-------+--------------+-------
 row2  |              |     0
 row4  | row2         |     1
 row6  | row4         |     2
 row8  | row6         |     3
 row5  | row2         |     1
 row9  | row5         |     2
(6 rows)

3、有分支,有orderby_fld (注意 row5 在 row4 前面)

bill@bill=>SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~')  
bill-#  AS t(keyid text, parent_keyid text, level int, branch text, pos int);
 keyid | parent_keyid | level |       branch        | pos 
-------+--------------+-------+---------------------+-----
 row2  |              |     0 | row2                |   1
 row5  | row2         |     1 | row2~row5           |   2
 row9  | row5         |     2 | row2~row5~row9      |   3
 row4  | row2         |     1 | row2~row4           |   4
 row6  | row4         |     2 | row2~row4~row6      |   5
 row8  | row6         |     3 | row2~row4~row6~row8 |   6
(6 rows)

4、没有分支,有 orderby_fld(注意 row5 在 row4 前面)

bill@bill=>SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0)  
bill-#  AS t(keyid text, parent_keyid text, level int, pos int);  
 keyid | parent_keyid | level | pos 
-------+--------------+-------+-----
 row2  |              |     0 |   1
 row5  | row2         |     1 |   2
 row9  | row5         |     2 |   3
 row4  | row2         |     1 |   4
 row6  | row4         |     2 |   5
 row8  | row6         |     3 |   6
(6 rows)
发布了155 篇原创文章 · 获赞 88 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_39540651/article/details/105387663