【问题标题】:how to get the all ascendants and descendants rows in sql with recursion如何通过递归获取sql中的所有祖先和后代行
【发布时间】:2012-01-26 14:16:48
【问题描述】:

我在ms sql server表名类别中有如下表数据

问题是我想获取祖父母、父母、兄弟姐妹、孩子和子孩子以及自己的数据。

我希望你明白我的意思,如果需要对我的要求进行更多说明,我可以编辑我的问题,只需在下面发表评论。

就我的尝试而言,我搜索了 stackoverflow,发现了很多使用父级获取完整分层数据的示例,但没有找到与传递子级并获取父级、子子级和自身相关的任何内容。

我也对使用linq 为我提供解决方案的解决方案持开放态度,因为这样我就可以在 Category 中获取完整的数据,并且可以在 .cs 页面上使用它们的 linq。

编辑: 如果我通过7 这是heritage CategoryId 那么查询应该返回以下行

【问题讨论】:

    标签: sql sql-server-2005 linq-to-sql recursion


    【解决方案1】:

    我这样做的方式是,创建一个函数并让它为程序的每个级别调用自己,如果您尝试输出数据并写出每个级别,或者让它在公共范围内组装某种数组,或静态变量/单例。

    它不漂亮,但递归很少。

    【讨论】:

    • 我在 sql 中寻找某种 cte
    • 我认为您可以将其作为存储过程来执行吗?并继续从自身调用存储过程来处理递归。
    【解决方案2】:

    答案是使用递归的“公用表表达式”或 CTE。这允许您构建层次结构的结构。下面是一个示例,根据此页面修改以匹配您的结构:http://msdn.microsoft.com/en-us/library/ms186243.aspx

    WITH CategoryStructured (ParentCategoryID, CategoryID, Description, Status, Level) 
    AS 
    ( 
    -- Anchor member definition 
    SELECT c.ParentCategoryID, c.CategoryID, c.Description, c.Status, 
    0 AS Level 
    FROM Category AS c 
    WHERE c.ParentCategoryID=0 
    UNION ALL 
    -- Recursive member definition 
    SELECT c.ParentCategoryID, c.CategoryID, c.Description, c.Status, 
    Level + 1 
    FROM Category AS c 
    
    INNER JOIN CategoryStructured AS c_parent 
    ON c.ParentCategoryID = c_parent.CategoryID 
    ) 
    -- Statement that executes the CTE 
    SELECT distinct cs.ParentCategoryID, cs.CategoryID, cs.Description, cs.Status, cs.Level 
    FROM 
    CategoryStructured cs, 
    
    
    (SELECT level,ParentCategoryID,CategoryID from CategoryStructured WHERE (categoryID = 4) OR (level = 1 AND parentCategoryID = 4)) as thisCategory 
    
    
    WHERE cs.level BETWEEN thisCategory.level - 1 AND thisCategory.level+1 
    AND ((thisCategory.level != 0 AND cs.ParentCategoryID = thisCategory.ParentCategoryID) 
    OR cs.categoryID = thisCategory.ParentCategoryID 
    OR cs.ParentCategoryID = thisCategory.CategoryID 
    OR cs.CategoryID = thisCategory.CategoryID)
    

    更新以反映您更新的问题。

    edit 我知道您可以通过添加的独特功能使上述内容基本上为您工作,但我在离开聊天后想到了一种更好的方法来处理这个问题:

    WITH CategoryStructured (ParentCategoryID, CategoryID, Description, Status, Level)
    AS
    (
    -- Anchor member definition
        SELECT c.ParentCategoryID, c.CategoryID, c.Description, c.Status, 
            0 AS Level
        FROM Categories AS c
        WHERE 
         (c.ParentCategoryID IS NULL AND c.categoryID = 7) -- when 7 is a top level category, then it is the root level
         OR (c.categoryID = (SELECT c2.parentCategoryID FROM Categories c2 WHERE c2.categoryID = 7)) -- when 7 is some non-top level category, then 7's parent is the root
        UNION ALL
    -- Recursive member definition
        SELECT c.ParentCategoryID, c.CategoryID, c.Description, c.Status, 
            Level + 1
        FROM Categories AS c
    
        INNER JOIN CategoryStructured AS c_parent
            ON c.ParentCategoryID = c_parent.CategoryID
    )
    -- Statement that executes the CTE
    SELECT cs.ParentCategoryID, cs.CategoryID, cs.Description, cs.Status, cs.Level
    FROM 
      CategoryStructured cs
    WHERE cs.level < 3
    ORDER BY cs.level
    

    【讨论】:

    • 它只会返回孩子,子孩子,但我想要父母,兄弟姐妹也
    • 我不明白 - 这将返回整个表,并确定每个级别。有什么问题?
    • 是的,我检查了它现在抱歉之前的评论我忘记了级别现在我必须查询这个表以获得我想要的结果
    • 好的,听起来这回答了你的问题。是否愿意将其标记为已批准?
    猜你喜欢
    • 2015-10-16
    • 1970-01-01
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 2021-03-03
    • 2011-01-31
    相关资源
    最近更新 更多