亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數(shù)據(jù)庫 > PostgreSQL > 正文

PostgreSQL樹形結(jié)構(gòu)的遞歸查詢示例

2020-01-31 15:20:39
字體:
供稿:網(wǎng)友

背景

處理不確定深度的層級結(jié)構(gòu),比如組織機(jī)構(gòu),一個(gè)常用的設(shè)計(jì)是在一張表里面保存 ID 和 Parent_ID ,并且通過自聯(lián)結(jié)的辦法構(gòu)造一顆樹。這種方式對寫數(shù)據(jù)的過程很友好,但是查詢過程就變得相對復(fù)雜。在不引入MPTT模型的前提下,必須通過遞歸算法來查詢某個(gè)節(jié)點(diǎn)和下級子節(jié)點(diǎn)。

Oracle提供的connect by擴(kuò)展語法,簡單好用。但是其他的RDBMS就沒這么人性化了(或者我不知道)。最近在項(xiàng)目中使用PostgreSQL來查詢樹形數(shù)據(jù),記錄一下。

構(gòu)造樣本數(shù)據(jù)

drop table if exists demo.tree_data;create table demo.tree_data ( id integer, code text, pid integer, sort integer);insert into demo.tree_data values(1, '中國', null, 1);insert into demo.tree_data values(2, '四川', 1, 1);insert into demo.tree_data values(3, '云南', 1, 2);insert into demo.tree_data values(4, '成都', 2, 1);insert into demo.tree_data values(5, '綿陽', 2, 2);	insert into demo.tree_data values(6, '武侯區(qū)', 4, 1);insert into demo.tree_data values(7, '昆明', 3, 1);	

connectby函數(shù)

如果安裝了 tablefunc 擴(kuò)展,就可以使用PG版本的connectby函數(shù)。這個(gè)沒有Oracle那么強(qiáng)大,但是可以滿足基本要求。

-- API 如下connectby(text relname, 			-- 表名稱  text keyid_fld, 			-- id字段  text parent_keyid_fld		-- 父id字段	  [, text orderby_fld ], 	-- 排序字段  text start_with, 			-- 起始行的id值  int max_depth				-- 樹深度,0表示無限  [, text branch_delim ])	-- 路徑分隔符
-- 基本用法如下,必須通過AS子句定義返回的字段名稱和類型select * 	from connectby('demo.tree_data', 'id', 'pid', 'sort', '1', 0, '~')	as (id int, pid int, lvl int, branch text, sort int);	-- 查詢結(jié)果id | pid | lvl | branch | sort----+-----+-----+---------+------ 1 | | 0 | 1 | 1 2 | 1 | 1 | 1~2 | 2 4 | 2 | 2 | 1~2~4 | 3 6 | 4 | 3 | 1~2~4~6 | 4 5 | 2 | 2 | 1~2~5 | 5 3 | 1 | 1 | 1~3 | 6 7 | 3 | 2 | 1~3~7 | 7(7 rows)
-- 僅僅使用基本用法,只能查詢出id的相關(guān)信息,如果要查詢code等其他字段,就需要通過額外的join操作來實(shí)現(xiàn)。select 	t.id, n.code, t.pid, p.code as pcode, lvl, branchfrom (	select * from connectby('demo.tree_data', 'id', 'pid', 'sort', '1', 0, '~')		as (id int, pid int, lvl int, branch text, sort int)) as t	left join demo.tree_data as n on (t.id = n.id)	left join demo.tree_data as p on (t.pid = p.id)order by t.sort ;	 id | code | pid | pcode | lvl | branch----+--------+-----+-------+-----+--------- 1 | 中國 | | | 0 | 1 2 | 四川 | 1 | 中國 | 1 | 1~2 4 | 成都 | 2 | 四川 | 2 | 1~2~4 6 | 武侯區(qū) | 4 | 成都 | 3 | 1~2~4~6 5 | 綿陽 | 2 | 四川 | 2 | 1~2~5 3 | 云南 | 1 | 中國 | 1 | 1~3 7 | 昆明 | 3 | 云南 | 2 | 1~3~7(7 rows)

PS:雖然通過join可以查詢出節(jié)點(diǎn)的code,但是branch部分不能直接轉(zhuǎn)換成對應(yīng)的code,使用上還是不太方便。

CTE語法

使用CTE語法,通過 with recursive 來實(shí)現(xiàn)樹形數(shù)據(jù)的遞歸查詢。這個(gè)方法雖然沒有connectby那么直接,但是靈活性和顯示效果更好。

-- with recursive cte as( -- 先查詢r(jià)oot節(jié)點(diǎn)  select id, code, pid, '' as pcode, code as branch from demo.tree_data where id = 1 union all -- 通過cte遞歸查詢r(jià)oot節(jié)點(diǎn)的直接子節(jié)點(diǎn)  select origin.id, origin.code, cte.id as pid, cte.code as pcode, cte.branch || '~' || origin.code from cte join demo.tree_data as origin on origin.pid = cte.id)select id,code, pid, pcode, branch,  -- 通過計(jì)算分隔符的個(gè)數(shù),模擬計(jì)算出樹形的深度 (length(branch)-length(replace(branch, '~', ''))) as lvlfrom cte;--  id | code | pid | pcode | branch  | lvl----+--------+-----+-------+-----------------------+----- 1 | 中國 | | | 中國   | 0 2 | 四川 | 1 | 中國 | 中國~四川  | 1 3 | 云南 | 1 | 中國 | 中國~云南  | 1 4 | 成都 | 2 | 四川 | 中國~四川~成都 | 2 5 | 綿陽 | 2 | 四川 | 中國~四川~綿陽 | 2 7 | 昆明 | 3 | 云南 | 中國~云南~昆明 | 2 6 | 武侯區(qū) | 4 | 成都 | 中國~四川~成都~武侯區(qū) | 3(7 rows)

執(zhí)行過程說明

從上面的例子可以看出,WITH RECURSIVE語句包含了兩個(gè)部分

  • non-recursive term(非遞歸部分),即上例中的union all前面部分
  • recursive term(遞歸部分),即上例中union all后面部分

執(zhí)行步驟如下

  • 執(zhí)行non-recursive term。(如果使用的是union而非union all,則需對結(jié)果去重)其結(jié)果作為recursive term中對result的引用,同時(shí)將這部分結(jié)果放入臨時(shí)的working table中
  • 重復(fù)執(zhí)行如下步驟,直到working table為空:用working table的內(nèi)容替換遞歸的自引用,執(zhí)行recursive term,(如果使用union而非union all,去除重復(fù)數(shù)據(jù)),并用該結(jié)果(如果使用union而非union all,則是去重后的結(jié)果)替換working table

以上面的query為例,來看看具體過程

執(zhí)行non-recursive query

-- step 1 執(zhí)行 select id, code, pid, '' as pcode, code as branch from demo.tree_data where id = 1 -- 結(jié)果集和working table為 id | code | pid | pcode | branch----+------+-----+-------+-------- 1 | 中國 | | | 中國

執(zhí)行recursive query

-- step 2 執(zhí)行遞歸,此時(shí)自引用cte中的數(shù)據(jù)是step 1的結(jié)果 select origin.id, origin.code, cte.id as pid, cte.code as pcode, cte.branch || '~' || origin.code from cte join demo.tree_data as origin on origin.pid = cte.id  -- 結(jié)果集和working table為 id | code | pid | pcode | branch ----+--------+-----+-------+--------------------- 2 | 四川 | 1 | 中國 | 中國~四川   3 | 云南 | 1 | 中國 | 中國~云南  

3、繼續(xù)執(zhí)行recursive query,直到結(jié)果集和working table為空

4、結(jié)束遞歸,將前三個(gè)步驟的結(jié)果集合并,即得到最終的WITH RECURSIVE的結(jié)果集。

嚴(yán)格來講,這個(gè)過程實(shí)現(xiàn)上是一個(gè)迭代的過程而非遞歸,不過RECURSIVE這個(gè)關(guān)鍵詞是SQL標(biāo)準(zhǔn)委員會(huì)定立的,所以PostgreSQL也延用了RECURSIVE這一關(guān)鍵詞。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對武林網(wǎng)的支持。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

欧美专区第一页| 国产三级精品三级在线专区| 在线成人午夜影院| 天天影视欧美综合在线观看| 国产一区在线观看免费| 色av成人天堂桃色av| 国产后进白嫩翘臀在线观看视频| 午夜欧美一区二区三区免费观看| 久久在线播放| 国产精品一区二区欧美黑人喷潮水| 视频在线这里都是精品| 亚洲区一区二| 日韩精品综合一本久道在线视频| 中文字幕日韩电影| 手机av免费在线| www.夜夜操.com| 波多野结衣av在线播放| 另类专区欧美蜜桃臀第一页| 国产一二三区在线观看| 99久久婷婷国产综合精品| 盗摄女厕thunder| 成人国产在线看| 免费视频一二三区| 日韩成人免费在线视频| 波多野结衣久久精品| 日批免费在线观看| 日韩精品1区2区3区| 欧洲精品乱码久久久久蜜桃| 91伊人久久大香线蕉| 黄视频免费在线看| 国产精品久久久久久精| 91福利区一区二区三区| 婷婷亚洲婷婷综合色香五月| 久久亚洲精品欧美| 久草热久草热线频97精品| 丰满人妻熟女aⅴ一区| 国产精品一区二区在线| 日韩中文字幕久久久经典网| 欧美性猛交xxxx免费看蜜桃| 午夜精品福利一区二区| 日韩午夜av电影| 国产精品视频男人的天堂| 国产视频欧美| 日本三级电影免费观看| 国产福利第一视频在线播放| 国产av人人夜夜澡人人爽| 欧美人体一区二区三区| 毛片毛片毛片毛片毛片毛片| 性欧美18—19sex性高清| 欧洲国产精品| 亚洲三级在线免费观看| 免费久久99精品国产自在现线| 精品爆乳一区二区三区无码av| 久久九九久精品国产免费直播| 视频一区国产| av亚洲精华国产精华| 天天夜碰日日摸日日澡性色av| 亚洲欧美激情诱惑| 欧美男男激情freegay| 五月天婷婷激情视频| 狠狠躁夜夜躁久久躁别揉| 久久精品国产亚洲aⅴ| 成人高清av| 97涩涩爰在线观看亚洲| 高清欧美电影在线| 毛片网站免费| 久久久国产精品黄毛片| 国产精品一品| 国产另类第一区| 欧美性极品少妇精品网站| 正在播放国产精品| 五月婷婷综合激情网| 国产成人无码一二三区视频| 你懂的亚洲视频| 免费资源在线观看| 国产色爱av资源综合区| 777精品久无码人妻蜜桃| 亚洲精品久久久久久久蜜桃臀| 国产手机视频在线| 91官网在线观看| 国产午夜久久久久| 免费又黄又爽又猛大片午夜| 欧洲精品99毛片免费高清观看| 91香蕉亚洲精品| 国产在线超碰| 人人澡人人透人人爽| 国产ts人妖一区二区| 神马伦理电影| 国产偷人爽久久久久久老妇app| 欧美经典影片视频网站| 瑟瑟视频在线| 国模一区二区三区私拍视频| 天堂在线资源视频| 欧美在线视频网站| 国产精品高潮久久久久无| 国产亚洲一区二区精品| 永久www成人看片| 日韩欧美2区| 日本熟妇成熟毛茸茸| 亚洲精品一区二区久| 日韩精品高清不卡| 佐山爱在线视频| 欧美www.| 91欧美视频在线| 国产白袜脚足j棉袜在线观看| 6080亚洲理论片在线观看| 亚洲国产免费看| 欧美丰满老妇厨房牲生活| 黄色片网站免费| 亚洲欧美日本视频在线观看| www在线免费观看视频| 国产精品88久久久久久妇女| 亚洲欧美久久| 久久久久久亚洲综合影院红桃| 91久久精品在线| 国产在线播放一区二区三区| 中文字幕亚洲综合久久菠萝蜜| 在线看黄网站| 亚洲精选久久| 久久综合网络一区二区| 精品伦精品一区二区三区视频| 国产91在线观看丝袜| 91黄色小网站| 精精国产xxxx视频在线野外| 隣の若妻さん波多野结衣| 亚洲影院中文字幕| 久久久久久青草| 成人无遮挡免费网站视频在线观看| 亚洲色图欧美在线| 亚洲精品动态| 精品不卡在线| 91精品视频网站| 国产绳艺sm调教室论坛| 色偷偷88888欧美精品久久久| 欧美性猛交一区二区三区精品| 小次郎av收藏家| 一区二区三区无码高清视频| 日韩深夜福利网站| 成人一区二区三区仙踪林| 青青青青国产视频| 黄色小视频免费看| 成人免费毛片日本片视频| 日韩av影视综合网| 亚洲人成色777777精品音频| 亚洲尤物视频在线| 亚洲一区欧美激情| 国产精品永久| 中文字幕欧美区| 91国产免费视频| 好吊色一区二区| 久久亚洲天堂网| 午夜视频免费在线| 亚洲jizzjizz日本少妇| 极品美女一区| 国产在线精品一区二区三区| 菠萝蜜视频在线观看一区| 97精品久久久| 精品久久久影院| 亚洲精品无码久久久久久| 亚洲女性喷水在线观看一区| 欧美爱爱视频免费看| 91欧美精品午夜性色福利在线| 欧美一区三区四区| 精品伦理一区二区| 麻豆影院在线观看| 潘金莲一级淫片aaaaaa播放1| 任你躁在线精品免费| 国模私拍一区二区国模曼安| 国产传媒一区二区| 日韩精品在线观看一区| 欧美激情欧美激情在线五月| 青青草原在线亚洲| 欧美日韩国产亚洲沙发| 中文有码在线| 欧美日韩午夜激情| 欧洲一级毛片| 亚洲美女视频一区| 欧美黄色一级视频| 最新在线中文字幕| 深夜福利影院在线观看| 亚洲精品亚洲人成人网| 久久99欧美| 欧美在线视频播放| 国产裸体无遮挡| 国产欧美精品日韩区二区麻豆天美| 最近中文字幕大全中文字幕免费| aa亚洲一区一区三区| 日本亚洲最大的色成网站www| 99成人在线| 91麻豆精品国产91久久久久推荐资源| 国产黄色一区二区| 男人的天堂在线播放| 美女一区二区三区视频| 成人免费在线观看av| 色狠狠色狠狠综合| 亚洲大肥女ass| 黄页在线免费观看| 国产精品嫩草影院av蜜臀| 欧美激情第一区| 国产精品一区二区三区网站| 久久成人一区二区| 国产欧美日韩在线看| 欧美丰满美乳xxⅹ高潮www| 亚洲欧美日韩人成在线播放| 日韩av免费| 性感美女极品91精品| 久久综合色88| 4438全国亚洲精品在线观看视频| 久久在线观看免费| 国产精品亚洲第五区在线| 黄色一级片在线观看| 日日噜噜噜夜夜爽爽狠狠| 美女啪啪无遮挡| 男人的天堂影院| eeuss影院在线观看第一页| 国产精品区一区二区三在线播放| 高h调教冰块play男男双性文| 国内精品偷拍视频| 日韩有码在线电影| 9999热视频| 天堂网视频在线观看| 中文字幕一区二区三区5566| 国产美女在线免费观看| 国产二区一区| 性无码专区无码| 人妻与黑人一区二区三区| 在线中文字幕不卡| 成年在线电影| 成人动漫免费在线观看| 中文字幕在线视频免费观看| 国产亚洲小视频| 久久久久88色偷偷免费| 91欧美一区二区| 欧美日韩一区二区三区在线看| 中文在线观看免费| 中文字幕中文字幕中文字幕亚洲无线| 日韩免费一二三区| 5858s免费视频成人| 成人在线黄色电影| 欧美影院在线播放| 欧美xxxx在线| 天天干视频在线观看| 亚洲成人黄色网址| 精品一区二区在线视频| 久久99久久99小草精品免视看| 色综合天天综合给合国产| 亚洲天堂日韩电影| 欧美视频在线观看一区二区| 国产午夜精品全部视频在线播放| 含羞草激情视频| 欧美日韩成人黄色| 视频在线一区二区三区| 日本欧美一区二区在线观看| 94色蜜桃网一区二区三区| brazzers欧美最新版视频| 青少年xxxxx性开放hg| 青青草99啪国产免费| 日韩午夜激情| 无码日韩精品一区二区| 澳门成人av网| 欧美视频一区二区三区| 视频成人永久免费视频| 国产黄色高清视频| 天天色棕合合合合合合合| 含羞草激情视频| www国产成人| 中国av一区二区三区| 头脑特工队2在线播放| 亚洲欧美日韩国产手机在线| 啊灬啊灬啊灬啊灬高潮在线看| 1024在线播放| 亚洲毛片在线看| 日韩在线视频不卡| 色噜噜国产精品视频一区二区| 国产日韩欧美三区| 日韩一区和二区| 久久精品一区二区三区中文字幕| 黑人中文字幕一区二区三区| 国产精品人人妻人人爽人人牛| h网站视频在线观看| 青春草在线观看| 91精品久久久久久久久久久久久久| 亚洲天堂网在线观看视频| 综合久久成人| 91精品国产麻豆国产自产在线| 亚洲国产三级在线| 国产极品久久久久久久久波多结野| 亚洲黄色小视频| 久久久精品在线视频| 日日噜噜噜夜夜爽爽狠狠| 伊人无码高清| 狠狠狠色丁香婷婷综合久久五月| 爱情岛论坛亚洲首页入口章节| 性一交一乱一色一视频麻豆| caoporn97免费视频公开| 成人性生活视频| 欧美亚洲国产bt| 先锋影院av| 日本成人在线不卡| xfplay先锋影音夜色资源站| 在线观看国产一区二区三区| 在线观看免费观看在线| 亚洲精品在线一区二区| 在线成人小视频| 午夜爱爱毛片xxxx视频免费看| 丝袜一区二区三区| 欧美福利电影网| 亚洲高清电影| 中国人xxxxx69免费视频| 免费av网站在线观看| 欧美视频精品在线| 国产精品22p| 亚洲视频免费在线观看| 98视频在线噜噜噜国产| 污版视频在线观看| 国产乱精品一区二区三区| 99久久国产综合精品女小说| 一区二区视频免费在线观看| 欧美日韩电影一区二区三区| 国产黄a三级三级三级av在线看| 醉酒壮男gay强迫野外xx| 在线电影院国产精品| 国产99久久久| 中文字幕在线观看一区二区| 久久久91精品国产一区二区三区| 国产农村妇女精品一二区| 男女视频免费看| 国产精品一区二区三区免费观看|