2012-05-18 81 views
20

我有設置這樣的材料表的議案:
項目 - 父使用MySQL查詢遍歷行進行遞歸樹

最終的結果,當我顯示的材料清單,它顯示是這樣的:

item 1 - parent 0  
    item 2 - parent 1  
    item 3 - parent 1  

最終的結果也可能是多層次是這樣的:

item 3 - parent 0  
    item 4 - parent 3  
    item 76 - parent 3  

它能夠成爲一種循環往復:

item 76 - parent 0  
    item 46 - parent 76  

item 46 - parent 0  
    item 25 - parent 46 

現在,我要麼只是從數據庫中獲取1級:

SELECT * FROM bom WHERE parentId = $itemId (shorthand)

或者從表中拉每一行,用我的遞歸函數,只是我需要的那些梳理,但是這顯然效率很低,因爲我可能只需要10行,但是我拉了10,000條記錄。遞歸函數的輸出將只是創建樹是這樣的:

item 1 
    item 2 
    item 3 
     item 4 
     item 76 
     item 46 
      item 25 

我所知道的是,我開始的第1項第5項可能有11父;他們不必順序。我想讓樹中的所有孩子分支。我怎麼能在MySQL中做這個查詢?

回答

35

回到2011年10月24日,有人發佈了question in the DBA StackExchange about tree traversal in MySQL。 MySQL的SQL無法支持它。

我在my answer to that question中寫了三(3)個存儲過程(GetParentIDByID,GetAncestry和GetFamilyTree)。希望這些信息可以幫助你構建你正在尋找的東西。

+0

優秀的程序。但是,然後'SELECT ID,GetFamilyTree(id)FROM pctable;'拋出一個錯誤:_ERROR 1292(22007):截斷不正確的DOUBLE值:'4,5'_。我試圖調試它,但徒勞無功。你有什麼想法嗎?謝謝 – idok

15

Bill Karwin發佈了一個幻燈片放映約heirarchical data在MySQL。如果更改數據庫設計是一種選擇,則還有其他一些吸引人的方式來存儲數據,以便查詢。他介紹的方法是:

  • 鄰接表
  • 路徑枚舉
  • 嵌套集合
  • 關閉表

幻燈片69有一個很好的表顯示每個方法的利弊,所以我建議你先看看幻燈片,看看哪種方法可能適合你,然後回頭看看如何實現它的細節。請注意,您選擇的設計(鄰接列表)僅爲提出的四種設計之一使得查詢子樹變得困難。如此說來,如果你不能改變你的設計,或者你想堅持鄰接表,那麼我必須同意迪迪埃的看法,你應該看看Quassnoi的文章"Hierarchical queries in MySQL"。這是一篇非常明確的文章,並解釋瞭如何高效地編寫查詢。

+2

偉大的資源。我爲了獲得像這樣的信息而付出了代價。謝謝! – phpmeh