PostgreSQL的递归查询(with recursive)

来源:互联网 发布:java中类的成员变量 编辑:程序博客网 时间:2024/06/07 22:59

文章转自:http://my.oschina.net/Kenyon/blog/55137


开发有需求,说需要对一张地区表进行递归查询,Postgres中有个 with recursive的查询方式,可以满足递归查询(一般>=2层)。 测试如下:

create table tb(id varchar(3) , pid varchar(3) , name varchar(10)); insert into tb values('002' , 0 , '浙江省'); insert into tb values('001' , 0 , '广东省'); insert into tb values('003' , '002' , '衢州市');  insert into tb values('004' , '002' , '杭州市') ; insert into tb values('005' , '002' , '湖州市');  insert into tb values('006' , '002' , '嘉兴市') ; insert into tb values('007' , '002' , '宁波市');  insert into tb values('008' , '002' , '绍兴市') ; insert into tb values('009' , '002' , '台州市');  insert into tb values('010' , '002' , '温州市') ; insert into tb values('011' , '002' , '丽水市');  insert into tb values('012' , '002' , '金华市') ; insert into tb values('013' , '002' , '舟山市');  insert into tb values('014' , '004' , '上城区') ; insert into tb values('015' , '004' , '下城区');  insert into tb values('016' , '004' , '拱墅区') ; insert into tb values('017' , '004' , '余杭区') ; insert into tb values('018' , '011' , '金东区') ; insert into tb values('019' , '001' , '广州市') ; insert into tb values('020' , '001' , '深圳市') ;
测试语句,查询浙江省及以下县市:
test=# with RECURSIVE cte as test-#  ( test(#  select a.id,a.name,a.pid from tb a where id='002' test(#  union all  test(#  select k.id,k.name,k.pid  from tb k inner join cte c on c.id = k.pid test(#  )select id,name from cte; id  |  name  -----+-------- 002 | 浙江省 003 | 衢州市 004 | 杭州市 005 | 湖州市 006 | 嘉兴市 007 | 宁波市 008 | 绍兴市 009 | 台州市 010 | 温州市 011 | 丽水市 012 | 金华市 013 | 舟山市 014 | 上城区 015 | 下城区 016 | 拱墅区 017 | 余杭区 018 | 金东区(17 rows)
如果查询有报错如死循环跳出,则需要检查下父字段与子字段的数据是否有相同。 

如果想按层次分别显示出来,也可以这么写 
test=# with RECURSIVE cte as
(
select a.id,cast(a.name as varchar(100)) from tb a where id='002'
union all 
select k.id,cast(c.name||'>'||k.name as varchar(100)) as name  from tb k inner join cte c on c.id = k.pid
)select id,name from cte ;
 id  |         name         
-----+----------------------
 002 | 浙江省
 003 | 浙江省>衢州市
 004 | 浙江省>杭州市
 005 | 浙江省>湖州市
 006 | 浙江省>嘉兴市
 007 | 浙江省>宁波市
 008 | 浙江省>绍兴市
 009 | 浙江省>台州市
 010 | 浙江省>温州市
 011 | 浙江省>丽水市
 012 | 浙江省>金华市
 013 | 浙江省>舟山市
 014 | 浙江省>杭州市>上城区
 015 | 浙江省>杭州市>下城区
 016 | 浙江省>杭州市>拱墅区
 017 | 浙江省>杭州市>余杭区
 018 | 浙江省>丽水市>金东区
(17 rows)




PS: MYSQL貌似还没出这么一种功能,  
附带说一下SqlServer的的递归查询,语法类似,不过把recursive去掉就可以了,如:
with cte as  (  select a.id,a.name,a.pid from tb a where id='002'  union all   select k.id,k.name,k.pid  from tb k inner join cte c on c.id = k.pid  )select id,name from cte;
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 家里电路坏了怎么办 深圳户口没房怎么办 深圳租凭合同怎么办 房屋续租水电费怎么办 二手房买到凶宅怎么办 公租房退休之后怎么办 深圳公务员无房怎么办 深圳安居房回执遗失怎么办 社保网注册不了怎么办 深圳怎么办少儿医保卡 少儿没缴纳医保怎么办 上海辞职后社保怎么办 辞职去上学社保怎么办 辞职后异地社保怎么办 个人不想交社保怎么办 离职去异地社保怎么办 离职到外省社保怎么办 辞职去外省社保怎么办 永康光伏补贴怎么办? 找到工作后档案怎么办 夫妻离婚后户口怎么办 异地档案辞职后怎么办 去网吧没有招聘怎么办 建筑工地老板不给钱怎么办 2018高压电工证怎么办 深圳户口怎么办户口卡 在深圳找不到工作怎么办 亲戚户口不迁出怎么办 深圳集体户口准生证怎么办 天津集体户口怎么办准生证 深圳集体户离职户口怎么办 解析包出现错误怎么办 信息登记号没有怎么办 博士非211 985怎么办 下雨考科目二怎么办 公司新装修有甲醛怎么办 驾驶证c换证怎么办 科目一上课迟到怎么办 滴滴预约不到车怎么办 科目二考挂4次怎么办 车行易骗了怎么办