3

鉴于我有这个结果集结构(多余的字段已被剥离)

Id | ParentId | Name | Depth
----------------------------

是否可以按树顺序返回记录,即ParentChildren如果 aChild是 a Parent,那么它们的Children,如果不是 thenSibling等等?例如,

Id | ParentId | Name | Depth
----------------------------
1    NULL       Major    1
2    1          Minor    2
3    1          Minor    2
4    3          Build    3
5    3          Build    3
6    1          Minor    2

/* etc, etc */

我能想到的唯一方法就是遵循这篇文章 -

使用嵌套集提高层次结构性能

并针对每条记录包含[LeftExtent][RightExtent]字段。现在文章中的 SQL 在Ids唯一时可以正常工作,但是在这种特定的树结构中,相同的记录Id可能会出现在树中的不同位置(ParentId显然字段不同)。我认为问题出在文章中的这个 SQL 中 -

  INSERT INTO @tmpStack
    (
      EmployeeID, 
      LeftExtent
    )
  SELECT TOP 1 EmployeeID, @counter 
  FROM Employee 
  WHERE ISNULL(ParentID, 0) = ISNULL(@parentid,0) 
  /* If the Id has already been added then record is not given [LeftExtent] or [RightExtent] values. */
  AND EmployeeID NOT IN (SELECT EmployeeID FROM @tmpStack) 

如何更改它以允许为具有重复的记录Ids提供 [LeftExtent] 和 [RightExtent] 值,或者我完全错过了一种更简单的方法来按我需要的顺序返回结果集?

4

3 回答 3

7

这是一个对我有用的技巧:

@ParentID 只是层次结构中的一个起点,但你可以传入 0(但我认为你使用 null 作为基本 ID,所以你会明白的)

有序排序的关键在于构建的排序键。

WITH RoleHierarchy (RoleID, [Role], [Description], ParentID, Editable, HierarchyLevel, SortKey) AS
(
   -- Base
   SELECT
        RoleID,
        [Role],
        [Description],
        ParentID,
        Editable,
        0 as HierarchyLevel,
        CAST(RoleID AS VARBINARY(300))
   FROM
        dbo.Roles       
   WHERE
        RoleID = @ParentID

   UNION ALL

   -- Recursive
   SELECT
        e.RoleID,
        e.[Role],
        e.[Description],
        e.ParentID,
        e.Editable,
        th.HierarchyLevel + 1 AS HierarchyLevel,
        CAST (th.SortKey + CAST (e.[Role] AS VARBINARY(100)) + CAST (e.[RoleID] AS VARBINARY(100)) AS VARBINARY(300))
   FROM
        Roles e
        INNER JOIN RoleHierarchy th ON e.ParentID = th.RoleID
    WHERE
        e.RoleID != 0
)

SELECT
    RoleID,
    ParentID,
    [Role],
    [Description],
    Editable,
    HierarchyLevel
FROM
    RoleHierarchy
WHERE
    RoleID != @ParentID
ORDER BY
    SortKey
于 2009-07-14T11:44:06.347 回答
3

您应该看看 SQL Server 2005 中的递归公用表表达式:

在你的情况下,这将是这样的:

WITH EmployeeCTE AS
(
   -- get the anchor
   SELECT ID, ParentID, Name, 0 as 'Depth'
   FROM Employee WHERE ParentID IS NULL

   -- recursively union lower levels
   UNION ALL
   SELECT e.ID, e.ParentID, e.Name, e.Depth+1
   FROM Employee e
   INNER JOIN EmployeeCTE ON e.ParentID = EmployeeCTE.ID
)
SELECT * FROM EmployeeCTE

这应该会给你一个很好的查询结果集,其中包含你正在寻找的数据。还是我错过了什么?

马克

于 2009-07-14T11:10:28.287 回答
0

如果您使用物化路径HIERARCHYID,您的生活会容易得多......

于 2009-07-14T13:57:53.943 回答