SQL:递归路径

时间:2010-04-29 14:10:33

标签: sql tree

是否可以在SQL中创建“树解析器”?

我有一张桌子:

ID Name Parent
1  a
2  b    1
3  c    1
4  d    3

现在我想要一个返回的SQL查询:

ID   PATH
1    /a
2    /a/b
3    /a/c
4    /a/c/d

这可能与SQL有关吗?它会让我更容易。真的很感激任何帮助!

5 个答案:

答案 0 :(得分:5)

在sql server 2005及更高版本中使用CTE,这是我必须执行此操作的片段:

WITH Paths([Level], [FullPath], [ID]) AS 
(
    SELECT 
        0 AS [Level], 
        Name AS FullPath, 
        ID
    FROM dbo.Entity
    WHERE (ParentEntityID IS NULL)

    UNION ALL

    SELECT 
        p.[Level] + 1 AS [Level], 
        CASE RIGHT(p.[FullPath], 1) 
        WHEN '\' THEN p.[FullPath] + c.[Name] 
        ELSE p.[FullPath] + '\' + c.[Name] 
    END AS FullPath, 
    c.ID
    FROM dbo.Entity AS c 
    INNER JOIN Paths AS p ON p.ID = c.ParentEntityID
)
SELECT [FullPath], [ID]
FROM Paths

答案 1 :(得分:1)

是的,看here。您可以使用“开始于”和“先前连接”语句,我过去曾使用过这个来在Web应用程序中创建面包屑。

答案 2 :(得分:1)

根据数据库服务器的使用情况,可能已经为您提供了此功能。否则,您可以创建一个调用自身以返回此信息的函数,或实现Materialized Path解决方案。

更新:

对于DB2,您可以使用Recursive Common Table Expressions

答案 3 :(得分:1)

在SQL数据库中表示树有几种不同的方法。我想我不太了解,但我知道Django Treebeard使用了3种不同的方法来做到这一点。如果您查看文档,它会对每种方式进行简短描述:

adjacency list - 您正在做的事情

materialized path - 文章:http://www.dba-oracle.com/t_sql_patterns_trees.htm

nested sets - 哦,这是维基百科:http://en.wikipedia.org/wiki/Nested_set_model

答案 4 :(得分:0)

假设我们有一个名为DLFolder的简单表,其中包含以下列:

| folderId | name | parentFolderId |

在Oracle中,您可以使用sys_connect_by_path操作。

select fo.folderId as folder_id, sys_connect_by_path(fo.name, '/') as relname
from DLFolder fo
start with fo.parentFolderId=0
connect by prior fo.folderId = fo.parentFolderId

将给出以下结果:

/1020_Training_Material
/1020_Training_Material/2000_IBBA
/1020_Training_Material/2000_IBBA/5000_FR
/1020_Training_Material/2000_IBBA/5050_NL

请参阅http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions164.htm