2010-09-07 39 views
3

我有一個表(這不能更改)如下所示:MySQL的自聯接

POST_ID | PARENT_ID | POST_NAME 

1  | 0   | Services 
4  | 1   | Development 
5  | 4   | Magento 
2  | 0   | Contact 

領域,「PARENT_ID」引用POST_ID形成一種自我指涉的外鍵。是否有可能編寫一個單一的查詢來連接一個職位,它的父母基於post_id?

舉例來說,如果我有POST_ID 5(Magento的),我能編寫一個查詢產生以下結果:

5 | Magento 
4 | Development 
1 | Services 

我知道這是很容易做到與多個查詢,但是,願望瞭解一個查詢是否可能。

謝謝:)

+0

MySQL沒有分層查詢支持 – 2010-09-07 21:00:18

+0

那是不是?有沒有辦法通過單個查詢來完成此任務? – aceenders 2010-09-07 21:02:04

回答

2

您正在使用adjacency list model組織您的分層數據。這種遞歸操作很困難的事實實際上是這種模型的一個主要缺點。

某些DBMS(如SQL Server 2005,Postgres 8.4和Oracle 11g)支持使用common table expressionsWITH關鍵字(也參見下面的@Quassnoi's註釋)的遞歸查詢。此功能允許輕鬆編寫這樣的查詢,但如上面註釋中提到的@OMG Ponies,MySQL不支持遞歸查詢。

您提到您無法對錶格進行任何更改,但可以添加額外的表格嗎?如果是的話,你可能會感興趣的檢查出下面的文章描述了另一種模式(在nested set model),這使得遞歸操作容易(可能):

此外,我還建議通過@Bill Karwin檢查出下面的介紹,對堆棧溢出的定期撰稿人:

演示文稿中描述的閉包表模型是嵌套集的非常有效的替代方案。他在他的SQL Antipatterns書(excerpt from the chapter on this topic [PDF])中進一步描述了這個模型。否則,您可能想要在應用程序中執行遞歸部分,下載所有數據,構建樹並遍歷它。

+0

'''Oracle'還支持從'2'版本開始的'CONNECT BY',它可以用來保留樹的順序。早期版本的PostgreSQL支持遞歸集合函數,可以用於相同的目的。 – Quassnoi 2010-09-07 21:17:44

+0

@Quassnoi:謝謝,沒有意識到這一點,讓我更新我的答案是更準確。與該UDF也很好的工作:) – 2010-09-07 21:24:14

2

當然,由於您使用的是MySQL,我建議將您的數據模型更改爲nested setsmaterialized path

但是,如果你被卡住鄰接表,這裏有一個方法來查詢它(需要創建用戶定義的函數):