设为首页 收藏本站
查看: 1060|回复: 0

[经验分享] PostgreSQL下迭代实现数据库递归查询

[复制链接]

尚未签到

发表于 2016-11-20 12:45:34 | 显示全部楼层 |阅读模式
  前言:
  考虑这样一个问题,A机构的上级机构是B,B机构的上级机构是C,C机构的上级机构是D,而D机构的上级机构是E。现在需要找出一个给定机构(例如E例如A)的所有上级机构。
  这种问题的典型表结构如下

机构(ins_id)上级机构(pre_ins_id)
AB
BC
CD
DE
  今天我们就是要解决诸如此类的问题。
  下面的函数以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;
DSC0000.jpg
 

  在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');
  结果如下图
DSC0001.png
 

  结束语:以上的SQL语句全部是在PostgreSQL中运行通过,由于各种数据库的语法的差别,在其他数据库中并不能保证不会报错。由于本人水平所限,如有错误,欢迎批评指正。
  参考文献:
  1. 《数据库系统概念》第六版第五章:高级SQL
  2. http://postgres.cz/wiki/PL/pgSQL_(en)
  版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-302962-1-1.html 上篇帖子: PostgreSQL修改sql表的方法汇总(转载) 下篇帖子: PostgreSQL的数据存储(十八)---数据存储的优化
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表