2010-09-07 38 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

但是,如果你被卡住邻接表,这里有一个方法来查询它(需要创建用户定义的函数):