婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > SQL 雙親節點查找所有子節點的實現方法

SQL 雙親節點查找所有子節點的實現方法

熱門標簽:互聯網電話外呼系統 千呼電話機器人可以試用嗎 電話機器人怎么代理商 電銷需要外呼系統嗎 我要地圖標注數量有限制嗎 零成本地圖標注賺錢 400電話辦理泰安 安卡拉地圖標注app 家庭農場地圖標注名稱怎樣起名

怎么保存樹狀結構的數據呢?在 SQL 中常用的是雙親節點法。創建表如下

CREATE TABLE category ( id LONG, parentId LONG, name String(20) )

INSERT INTO category VALUES ( 1, NULL, 'Root' )
INSERT INTO category VALUES ( 2, 1, 'Branch1' )
INSERT INTO category VALUES ( 3, 1, 'Branch2' )
INSERT INTO category VALUES ( 4, 3, 'SubBranch1' )
INSERT INTO category VALUES ( 5, 2, 'SubBranch2' )

其中,parent id 表示父節點, name 是節點名稱。

假設當前欲獲取某一節點下所有子節點(獲取后代 Descendants),該怎么做呢?如果使用程序(Java/PHP)遞歸調用,那么將在數據庫與本地開發語言之間來回訪問,效率之低可想而知。于是我們希望在數據庫的層面就可以完成,——該怎么做呢?

遞歸法

經查詢,最好的方法(個人覺得)是 SQL 遞歸 CTE 的方法。所謂 CTE 是 Common Table Expressison 公用表表達式的意思。網友評價說:“CTE 是一種十分優雅的存在。CTE 所帶來最大的好處是代碼可讀性的提升,這是良好代碼的必須品質之一。使用遞歸 CTE 可以更加輕松愉快的用優雅簡潔的方式實現復雜的查詢。”——其實我對 SQL 不太熟悉,大家谷歌下其意思即可。

怎么用 CTE 呢?我們用小巧數據庫 SQLite,它就支持!別看他體積不大,卻也能支持最新 SQL99 的 with 語句,例子如下。

WITH w1( id, parentId, name) AS 
(		SELECT 
			category.id, 
			category.parentId, 
            category.name
		FROM 
			category 
		WHERE 
			id = 1
	UNION ALL 
		SELECT 
			category.id, 
			category.parentId, 
            category.name
		FROM 
			category JOIN w1 ON category.parentId= w1.id
) 

SELECT * FROM w1;其中 WHERE id = 1 是那個父節點之 id,你可以改為你的變量。簡單說,遞歸 CTE 最少包含兩個查詢(也被稱為成員)。第一個查詢為定點成員,定點成員只是一個返回有效表的查詢,用于遞歸的基礎或定位點。第二個查詢被稱為遞歸成員,使該查詢稱為遞歸成員的是對 CTE 名稱的遞歸引用是觸發。在邏輯上可以將 CTE 名稱的內部應用理解為前一個查詢的結果集。遞歸查詢沒有顯式的遞歸終止條件,只有當第二個遞歸查詢返回空結果集或是超出了遞歸次數的最大限制時才停止遞歸。遞歸次數上限的方法是使用 MAXRECURION。

相應地給出查找所有父節點的方法(獲取祖先 Ancestors,就是把 id 和 parentId 反過來)

WITH w1( id, parentId, name, level) AS  
(    SELECT  
        id,  
        parentId,  
        name,
        0 AS level
      FROM  
        category  
      WHERE  
        id = 6 
    UNION ALL  
      SELECT  
        category.id,  
        category.parentId,  
        category.name ,
        level + 1
      FROM  
        category JOIN w1 ON category.id= w1.parentId
 )  
SELECT * FROM w1; 

無奈的 MySQL

SQLite ok 了,而 MySQL 呢?

在另一邊廂,大家都愛用的 MySQL 卻無視 with 語句,官網博客上明確說明是壓根不支持,十分不方便,明明可以很簡單事情為什么不能用呢?——而且 MySQL 也好像沒有計劃在將來的新版本中添加 with 的 cte 功能。于是大家想出了很多辦法。其實不就是一個遞歸程序么——應該不難——寫函數或者存儲過程總該行吧?沒錯,的確如此,——寫遞歸不是問題,問題是用 SQL 寫就是個問題——還是那句話,“隔行如隔山”,雖然有點夸張的說法,但我想既懂數據庫又懂各種數據庫方言寫法(存儲過程)的人應該不是很多吧~,——不細究了,反正就是代碼帖來貼去唄~

我這里就不貼 SQL 了,可以看這里的,《MySQL中進行樹狀所有子節點的查詢》

至此,我們的目的可以說已經達到了,而且還不錯,因為這是不限層數的(以前 CMS 常說的“無限級”分類)。——其實,一般情況下,層數超過三層就很多,很復雜了,一般用戶如無特殊需求,也用不上這么多層。于是,在給定層數的約束下,可以寫標準的 SQL 來完成該任務——盡管有點寫死的感覺~~

SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parentId = t1.id
LEFT JOIN category AS t3 ON t3.parentId = t2.id
LEFT JOIN category AS t4 ON t4.parentId = t3.id
WHERE t1.id= 1

相應地給出查找所有父節點的方法(獲取祖先 Ancestors,就是把 id 和 parentId 反過來)

SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4 
FROM category AS t1 
 LEFT JOIN category AS t2 ON t2.id= t1.parentId
 LEFT JOIN category AS t3 ON t3.id= t2.parentId
 LEFT JOIN category AS t4 ON t4.id= t3.parentId

WHERE t1.id= 10優化版本

但是生成的結果和第一個例子相比起來有點奇怪,而且不好給 Java 用,——那就再找找其他例子

SELECT   
            p1.id,
            p1.name,
            p1.parentId as parentId,
            p2.parentId as parent2_id,
            p3.parentId as parent3_id,
            p4.parentId as parent4_id,
            p5.parentId as parent5_id,
   p6.parentId as parent6_id
FROM category p1
LEFT JOIN   category p2 on p2.id = p1.parentId
LEFT JOIN   category p3 on p3.id = p2.parentId
LEFT JOIN   category p4 on p4.id = p3.parentId 
LEFT JOIN   category p5 on p5.id = p4.parentId 
LEFT JOIN   category p6 on p6.id = p5.parentId
WHERE 1 IN   (p1.parentId,
                   p2.parentId,
                   p3.parentId,
                   p4.parentId,
                   p5.parentId,
                   p6.parentId)

ORDER BY 1, 2, 3, 4, 5, 6, 7; 這個總算像點樣子了,結果是這樣子的。

相應地給出查找所有父節點的方法(獲取祖先 Ancestors,就是把 id 和 parentId 反過來, 還有改改 IN 里面的字段名)

SELECT   
        p1.id, 
        p1.name, 
        p1.parentId as parentId, 
        p2.parentId as parent2_id, 
        p3.parentId as parent3_id
  FROM  category p1 
  LEFT JOIN  category p2 on p2.parentId  = p1.id
  LEFT JOIN  category p3 on p3.parentId  = p2.id
  WHERE 9 IN  (p1.id,  
            p2.id,  
            p3.id)  
  ORDER BY 1, 2, 3; 

這樣就很通用啦~無論你 SQLite 還是 MySQL。

其他查詢:

查詢直接子節點的總數:

SELECT c.*
,    (SELECT COUNT(*) FROM category c2 WHERE c2.parentId = c.id) 
    AS direct_children
FROM category c

•使用 with 語句遞歸,通俗易懂的例子(英文),我第一個成功的例子就是從這里 copy 的,另外還可以查層數 level 和反向的父節點:https://www.valentina-db.com/dokuwiki/doku.php?id=valentina:articles:recursive_query

•標準寫法的出處(英文):http://stackoverflow.com/questions/20215744/how-to-create-a-mysql-hierarchical-recursive-query

•很好的總結貼(英文):http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

•SQlite with 語句用法中文翻譯(太晦澀,不懂鳥) http://blog.csdn.net/aflyeaglenku/article/details/50978986

•利用閉包做的樹結構(書上說這個方法最好,但同時覺得也很高級,英文)http://charlesleifer.com/blog/querying-tree-structures-in-sqlite-using-python-and-the-transitive-closure-extension/

以上這篇SQL 雙親節點查找所有子節點的實現方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • MySQL遞歸查詢樹狀表的子節點、父節點具體實現

標簽:文山 大同 來賓 黃山 新鄉 東營 濱州 池州

巨人網絡通訊聲明:本文標題《SQL 雙親節點查找所有子節點的實現方法》,本文關鍵詞  SQL,雙親,節點,查找,所有,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《SQL 雙親節點查找所有子節點的實現方法》相關的同類信息!
  • 本頁收集關于SQL 雙親節點查找所有子節點的實現方法的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    日本韩国欧美国产| 亚洲18女电影在线观看| 国内精品国产三级国产a久久 | 丁香婷婷深情五月亚洲| 亚洲精品国久久99热| 精品国产91九色蝌蚪| 99亚偷拍自图区亚洲| 日本欧美韩国一区三区| 国产精品丝袜一区| 日韩欧美美女一区二区三区| 国产成都精品91一区二区三| 午夜久久久久久| 玉米视频成人免费看| 久久久久一区二区三区四区| 欧美一区二区三区男人的天堂| 91蝌蚪porny成人天涯| 久久99热99| 日韩成人精品视频| 亚洲精品视频在线观看免费| 国产欧美一区二区精品性色| 日韩一区二区在线观看| 欧美在线小视频| 欧美在线观看一区| 91黄色激情网站| 91福利国产精品| 9久草视频在线视频精品| 丁香六月综合激情| 成人黄色小视频在线观看| 国产成人精品网址| 国产福利91精品一区二区三区| 国产自产高清不卡| 精品一区二区三区欧美| 韩国v欧美v亚洲v日本v| 国产在线播放一区| 懂色av一区二区夜夜嗨| 国产精品一区久久久久| 国产成人精品亚洲777人妖| 国产大片一区二区| 成人免费视频一区| 91色综合久久久久婷婷| 91蜜桃免费观看视频| 一本一道久久a久久精品| 94-欧美-setu| 91久久线看在观草草青青| 91久久精品一区二区二区| 欧美另类变人与禽xxxxx| 在线成人免费观看| 欧美一区二区三区在线观看| 精品国产一区二区在线观看| 国产午夜亚洲精品午夜鲁丝片| 久久久久久免费网| 中文字幕五月欧美| 中文字幕一区在线观看视频| 怡红院av一区二区三区| 亚洲最大的成人av| 日韩激情视频在线观看| 久久综合综合久久综合| 国产精品一区二区三区乱码| 成人看片黄a免费看在线| av福利精品导航| 国产福利不卡视频| 一本一道久久a久久精品综合蜜臀| 欧日韩精品视频| 日韩精品中午字幕| 国产日本欧洲亚洲| 一区二区三区小说| 国产在线精品一区二区夜色 | 一区二区三区四区不卡在线| 丝瓜av网站精品一区二区| 九九视频精品免费| 国产成人精品亚洲777人妖| 在线观看91视频| 91精品麻豆日日躁夜夜躁| 中文字幕欧美激情| 亚洲高清三级视频| 国产成人在线色| 欧美日韩国产另类不卡| 欧美videos中文字幕| 日韩一区有码在线| 麻豆视频一区二区| av日韩在线网站| 日韩女优电影在线观看| 国产精品久久国产精麻豆99网站| 日韩精品亚洲一区二区三区免费| 国产精品99久久久久久似苏梦涵 | 成人免费一区二区三区视频| 亚洲成人黄色影院| 91美女视频网站| 2019国产精品| 依依成人综合视频| 99精品欧美一区| 欧美精品一区二区在线播放 | 日韩一级大片在线| 国产精品色哟哟网站| 美日韩一区二区| 欧美中文字幕一区二区三区亚洲| 国产精品水嫩水嫩| 国产乱码精品一区二区三区五月婷| 亚洲最新视频在线观看| 亚洲欧美日韩中文字幕一区二区三区 | 欧美不卡123| 国产美女视频一区| 精品在线播放免费| 久久久噜噜噜久久人人看 | 国产农村妇女精品| 91亚洲国产成人精品一区二区三| 国产精品情趣视频| 欧美草草影院在线视频| 亚洲电影在线免费观看| 国产高清成人在线| 日韩一卡二卡三卡国产欧美| 午夜影院久久久| 欧美在线看片a免费观看| 亚洲精品精品亚洲| 欧美日免费三级在线| 亚洲美女屁股眼交3| 色欲综合视频天天天| 一区二区三区四区高清精品免费观看 | 国产精品欧美久久久久一区二区| 久久99精品国产麻豆婷婷洗澡| 欧美亚洲国产一区二区三区va| 亚洲精品中文字幕乱码三区| 欧美亚洲一区二区在线| 国产乱子轮精品视频| 欧美成人一级视频| 久久精品国产秦先生| 精品久久久久久久久久久久久久久| 久久精品久久综合| 国产精品天天摸av网| 国产69精品久久久久毛片| 亚洲国产成人午夜在线一区| 91视频你懂的| 亚洲bdsm女犯bdsm网站| 91精品国产综合久久久久久漫画| 毛片av一区二区| 国产欧美日韩精品a在线观看| 懂色av一区二区夜夜嗨| 亚洲人成伊人成综合网小说| 欧美三级一区二区| 麻豆精品国产传媒mv男同 | 蜜臀va亚洲va欧美va天堂 | 日韩欧美另类在线| 激情综合五月婷婷| 国产精品天天看| 色婷婷av一区二区三区gif| 天天操天天综合网| 久久色成人在线| 97se亚洲国产综合自在线观| 午夜电影久久久| 国产色综合一区| 欧美精品第1页| 国产精品综合一区二区| 亚洲最新视频在线观看| 精品国产乱码久久久久久1区2区| 在线观看视频91| 久久99精品久久久久久国产越南 | 亚洲午夜成aⅴ人片| 欧美精品1区2区| 欧美日本一道本在线视频| 一个色在线综合| 国产日韩欧美精品在线| 欧美日韩国产另类一区| 99精品一区二区三区| 激情深爱一区二区| 最新久久zyz资源站| 欧美一区二区福利在线| av一二三不卡影片| 美女www一区二区| 亚洲一区日韩精品中文字幕| 亚洲欧洲日本在线| 精品国产髙清在线看国产毛片| 色香蕉久久蜜桃| 99精品在线免费| 国产福利精品一区二区| 日韩主播视频在线| 亚洲少妇30p| 亚洲国产精品t66y| 国产婷婷色一区二区三区在线| 欧美一区三区四区| 在线观看不卡视频| 一本大道久久a久久精品综合| 精品一区二区三区视频| 日韩精品一级中文字幕精品视频免费观看 | 国产一区二区三区四区五区入口 | 久久亚洲精品小早川怜子| 91麻豆精品国产91久久久久| 色综合久久六月婷婷中文字幕| 成人性生交大片免费看视频在线| 久久国产精品免费| 日本不卡的三区四区五区| 日韩高清一区二区| 亚洲午夜免费电影| 日日摸夜夜添夜夜添国产精品 | 国产欧美日韩三级| 国产亚洲精品超碰| 国产欧美日韩三区| 一区二区三区蜜桃| 日本中文字幕一区| 国产麻豆精品在线观看| 99国产精品视频免费观看|