代码之家  ›  专栏  ›  技术社区  ›  Chris

SQL:递归路径

  •  3
  • Chris  · 技术社区  · 15 年前

    是否可以在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 回复  |  直到 15 年前
        1
  •  1
  •   D'Arcy Rittich    15 年前

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

    更新:

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

        2
  •  5
  •   Troy    14 年前

    使用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
    
        3
  •  1
  •   Otávio Décio    15 年前

    是的,看 here . 您可以使用“start with”和“connect by previous”语句,我过去曾用它在Web应用程序中创建breadcrumbs。

        4
  •  1
  •   rescdsk    15 年前

    有几种不同的方法来表示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

        5
  •  0
  •   p.mesotten    13 年前

    假设我们有一个名为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