如何使用公用表表达式在SQL Server中进行分层排序

时间:2012-08-31 11:29:21

标签: sql-server common-table-expression

  

可能重复:
  A real recursion with CTE?

给定一个引用自身的分层表,例如具有以下列的Employee表:

Table      Employee
    Column Id INT NOT NULL
    Column ParentId INT NOT NULL (references Id)
    Column Name NVARCHAR(60) NOT NULL

以下查询将为我提供以给定EmployeeId为根的所有记录:

DECLARE @EmployeeId INT = <%insert EmployeeId here%>;

WITH CDE AS
(
    SELECT
        *,
        0 AS Level
    FROM
        collaboration.Employee AS E
    WHERE
        Id = @EmployeeId
    UNION ALL
    SELECT
        E.*,
        CDE.Level + 1 AS Level
    FROM
        collaboration.Employee AS E
        INNER JOIN
        CDE ON E.ParentId = CDE.Id AND E.Id <> 0
)
SELECT DISTINCT
    CDE.*
FROM
    CDE
ORDER BY
    CDE.Level

我想要的是能够按“分支”排序然后“水平”,如果这是有道理的。所以给出下表:

1    0    John Smith
2    1    John Doe
3    1    Jane Williams
4    2    Ian Bond
5    2    James Fleming

我希望结果如下:

1    0    John Smith
2    1    John Doe
4    2    Ian Bond
5    2    James Fleming
3    1    Jane Williams

我想要一个不涉及构建字符串以便于排序的解决方案。如果无法解决问题,我想知道原因。

1 个答案:

答案 0 :(得分:2)

;WITH CDE AS 
( 
    SELECT 
        *, 
        0 AS Level,
        convert(nvarchar(50),id) as EPath
    FROM 
        collaboration.Employee AS E 
    WHERE 
        Id = @EmployeeId 
    UNION ALL 
    SELECT 
        E.*, 
        CDE.Level + 1 AS Level ,
        convert(nvarchar(50),Epath+'/'+CONVERT(nvarchar(5),e.id))
    FROM 
        collaboration.Employee AS E 
        INNER JOIN 
        CDE ON E.ParentId = CDE.Id AND E.Id <> 0 
) 
SELECT DISTINCT 
    CDE.* 
FROM 
    CDE 
ORDER BY 
    EPath

顺便说一句,SQL Server 2008只有HierarchyID数据类型。