PostgreSQL递归查询示例
2019-06-14 13:32 abce 阅读(15258) 评论(2) 编辑 收藏 举报PostgreSQL提供了WITH语句,允许你构造用于查询的辅助语句。这些语句通常称为公共表表达式或cte。cte类似于只在查询执行期间存在的临时表。
递归查询是指递归CTE的查询。递归查询在很多情况下都很有用,比如查询组织结构、物料清单等层次数据
下面演示了递归CTE的语法:
1 2 3 4 5 | WITH RECURSIVE cte_name( CTE_query_definition -- non-recursive term UNION [ ALL ] CTE_query definion -- recursive term ) SELECT * FROM cte_name; |
递归CTE有三个元素:
1.非递归项:非递归项是CTE查询定义,它构成CTE结构的基本结果集。
2.递归项:递归项是使用UNION或UNION ALL操作符将一个或多个CTE查询定义与非递归项连接起来。递归项引用CTE名称本身。
3.终止检查:当上一个迭代没有返回任何行时,递归将停止。
PostgreSQL按以下顺序执行递归CTE:
1.执行非递归项来创建基本结果集(R0)。
2.以Ri作为输入执行递归项,返回结果集Ri+1作为输出。
3.重复步骤2,直到返回一个空集。(终止检查)
4.返回最终的结果集,它是一个并集,或者是所有结果集R0、R1、……Rn的并集
我们将创建一个新表来演示PostgreSQL递归查询。
1 2 3 4 5 | CREATE TABLE employees ( employee_id serial PRIMARY KEY , full_name VARCHAR NOT NULL , manager_id INT ); |
员工表由三个列组成:employee_id、manager_id和全名。manager_id列指定employee的manager id。
下面的语句将示例数据插入employees表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | INSERT INTO employees ( employee_id, full_name, manager_id ) VALUES (1, 'Michael North' , NULL ), (2, 'Megan Berry' , 1), (3, 'Sarah Berry' , 1), (4, 'Zoe Black' , 1), (5, 'Tim James' , 1), (6, 'Bella Tucker' , 2), (7, 'Ryan Metcalfe' , 2), (8, 'Max Mills' , 2), (9, 'Benjamin Glover' , 2), (10, 'Carolyn Henderson' , 3), (11, 'Nicola Kelly' , 3), (12, 'Alexandra Climo' , 3), (13, 'Dominic King' , 3), (14, 'Leonard Gray' , 4), (15, 'Eric Rampling' , 4), (16, 'Piers Paige' , 7), (17, 'Ryan Henderson' , 7), (18, 'Frank Tucker' , 8), (19, 'Nathan Ferguson' , 8), (20, 'Kevin Rampling' , 8); |
下面的查询返回id为2的经理的所有下属。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | WITH RECURSIVE subordinates AS ( SELECT employee_id, manager_id, full_name FROM employees WHERE employee_id = 2 UNION SELECT e.employee_id, e.manager_id, e.full_name FROM employees e INNER JOIN subordinates s ON s.employee_id = e.manager_id ) SELECT * FROM subordinates; |
上面sql的工作原理:
1.递归CTE subordinates定义了一个非递归项和一个递归项。
2.非递归项返回基本结果集R0,即id为2的员工。
1 2 3 | employee_id | manager_id | full_name -------------+------------+------------- 2 | 1 | Megan Berry |
递归项返回员工id 2的直接下属。这是employee表和subordinates CTE之间连接的结果。递归项的第一次迭代返回以下结果集:
1 2 3 4 5 6 | employee_id | manager_id | full_name -------------+------------+----------------- 6 | 2 | Bella Tucker 7 | 2 | Ryan Metcalfe 8 | 2 | Max Mills 9 | 2 | Benjamin Glover |
PostgreSQL重复执行递归项。递归成员的第二次迭代使用上述步骤的结果集作为输入值,返回该结果集:
1 2 3 4 5 6 7 | employee_id | manager_id | full_name -------------+------------+----------------- 16 | 7 | Piers Paige 17 | 7 | Ryan Henderson 18 | 8 | Frank Tucker 19 | 8 | Nathan Ferguson 20 | 8 | Kevin Rampling |
第三次迭代返回一个空的结果集,因为没有员工向id为16、17、18、19和20的员工报告。
PostgreSQL返回最终结果集,该结果集是由非递归和递归项生成的第一次和第二次迭代中的所有结果集的并集。
1 2 3 4 5 6 7 8 9 10 11 12 13 | employee_id | manager_id | full_name -------------+------------+----------------- 2 | 1 | Megan Berry 6 | 2 | Bella Tucker 7 | 2 | Ryan Metcalfe 8 | 2 | Max Mills 9 | 2 | Benjamin Glover 16 | 7 | Piers Paige 17 | 7 | Ryan Henderson 18 | 8 | Frank Tucker 19 | 8 | Nathan Ferguson 20 | 8 | Kevin Rampling (10 rows ) |
在本教程中,已经学习了如何使用递归cte构造PostgreSQL递归查询。
参考地址:http://www.postgresqltutorial.com/postgresql-recursive-query/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2017-06-14 rhel7 ifconfig command not found