前言:
考虑这样一个问题,A机构的上级机构是B,B机构的上级机构是C,C机构的上级机构是D,而D机构的上级机构是E。现在需要找出一个给定机构(例如E例如A)的所有上级机构。
这种问题的典型表结构如下
机构(ins_id) | 上级机构(pre_ins_id) |
A | B |
B | C |
C | D |
D | E |
今天我们就是要解决诸如此类的问题。
下面的函数以in_ins_id为参数,计算并返回该机构的所有直接或者间接上级机构并返回他们组成的集合
CREATE FUNCTION getAllPreIns(VARCHAR) --接收一个VARCHAR参数 RETURNS TABLE(ins_id VARCHAR) --返回一个table LANGUAGE plpgsql AS $function$ --function标识 DECLARE in_ins_id ALIAS FOR $1; --把接收的的参数放在in_ins_id变量中 BEGIN CREATE TEMPORARY TABLE ins(ins_id VARCHAR(8)); --该临时表将返回最终的数据 CREATE TEMPORARY TABLE new_ins(ins_id VARCHAR(8)); --存储前一次迭代中找到的数据 CREATE TEMPORARY TABLE temp(ins_id VARCHAR(8)); --用于存放对集合操作时的中间数据 --先把in_ins_id的上级机构插入new_ins表中 INSERT INTO new_ins SELECT pre_ins_id FROM ins_table WHERE ins_table.ins_id = in_ins_id; LOOP --将new_ins中的数据插入到ins中 INSERT INTO ins SELECT new_ins.ins_id FROM new_ins; --将new_ins中ins_id的上级机构插入到temp中 INSERT INTO temp (SELECT ins_table.pre_ins_id FROM new_ins, ins_table WHERE new_ins.ins_id = ins_table.ins_id) EXCEPT --防止出现机构环如A的上级机构是B,B的上级机构是C,C的上级机构是A (SELECT ins.ins_id FROM ins); DELETE FROM new_ins; --清空new_ins INSERT INTO new_ins --保存temp SELECT temp.ins_id FROM temp; DELETE FROM temp; EXIT WHEN NOT EXISTS (SELECT new_ins.ins_id FROM new_ins); --知道没有上级机构市循环终止 END LOOP; RETURN QUERY SELECT ins.ins_id FROM ins; --返回 END; $function$ --function标识
假设我们传入的参数是A,在此function中,我们先找到A的上级机构B并存放在new_ins中,如此循环,直到某次循环中没有新的机构加进来才停止。
此过程所用到的4个表
- ins:存储要返回的元素集合
- new_ins:存储每一次迭代中找到的上级机构,并在下一次迭代中插入到表ins中
- temp:临时存储每一次迭代中找到的上级机构
- Ins_table:我们的原始机构表(如下图)
SELECT ins_id, pre_ins_id FROM ins_table;
在LOOP循环之前我们先把in_ins_id的所有直接上级机构插入到表new_ins中。LOOP循环开始首先将new_ins中的所有机构插入到ins中。然后为new_ins中的所有机构计算上级机构,并去掉此前已经计算出的in_ins_id的上级机构,把余下的机构插入到temp中。最后用temp的数据替换new_ins。当new_ins为空时,LOOP终止。
最后我们在postgresql中调用该函数
SELECT * FROM getAllPreIns('A');
结果如下图
结束语:以上的SQL语句全部是在PostgreSQL中运行通过,由于各种数据库的语法的差别,在其他数据库中并不能保证不会报错。由于本人水平所限,如有错误,欢迎批评指正。
参考文献:
1. 《数据库系统概念》第六版第五章:高级SQL
2. http://postgres.cz/wiki/PL/pgSQL_(en)
版权声明:本文为博主原创文章,未经博主允许不得转载。
相关推荐
树PostgreSQL的递归查询树PostgreSQL的递归查询树PostgreSQL的递归查询
PostgreSql+PostGis 创建空间数据库
Postgresql数据库运维笔记 数据库运维.pdf
本书主要介绍PostgreSQL的基本概念及应用技巧,内容包括:PostgreSQL基础知识、PostgreSQL快速入门、PostgreSQL管理、PostgreSQL数据库实现、规则与触发器、扩展PostgreSQL、服务器编程接口、PostgreSQL的C语言库...
个人完整的源码安装步骤,希望对你有用。亲测可用。Centos6.2下以JDBC驱动连接任意数据库实现读操作
PostgreSQL数据库内核分析PostgreSQL数据库内核分析PostgreSQL数据库内核分析PostgreSQL数据库内核分析PostgreSQL数据库内核分析PostgreSQL数据库内核分析PostgreSQL数据库内核分析PostgreSQL数据库内核分析...
经常碰到客户电脑操作系统重装或要更换电脑,而数据库恢复或迁移是个非常麻烦的事情。通过此工具则可以非常方便的进行恢复,不需要重装PG数据库及库。
postgresql数据库备份和恢复文档资料,详细介绍了PostgreSQL数据库的备份与恢复 方法,值得学习下
1.nacos服务,适配postgresql数据库。 2.提供nacos,postgresql的创建nacos数据库脚本。 3.nacos/conf/nacos-pg.sql数据库脚本文件。 4.nacos版本1.4.2。
C# 操作PostgreSQL 数据库 .
postgreSQL数据迁移到达梦数据库操作
postgresql数据库jdbc驱动,jar包。。。。。。。。。。。。
Navicat for PostgreSQL是一套专为PostgreSQL设计的强大数据库管理及开发工具。它可以用于任何版本 7.5 或以上的 PostgreSQL 数据库服务器,并支持大部份 PostgreSQL最新版本的功能,包括触发器、函数、管理用户等。...
选择数据库类型,配置数据库来源,选择需要生成的表,一键生成数据库文档
asp连接postgresql数据库 的源码
Window 下的PostgreSQL 数据库备份和恢复工具[GUI],供大家一起共同分享使用。
.PostGreSQL安装部署系列:Centos 7.9 安装指定PostGreSQL-15版本数据库
经过长期整理的Postgresq数据库文档,可以很方便查找函数,技巧,常用命令
postgresql数据库的一个关于租赁DVD的商店的例子,里面详细介绍了DVD租赁的一些逻辑表。
主要给大家介绍了关于PostgreSQL图(graph)的递归查询的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用PostgreSQL具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧