SQL父子树按DEPTH和显示顺序排序

时间:2013-07-15 21:22:37

标签: sql sql-server sql-server-2008

我有这个查询创建了类别的层次结构。它很棒。现在我正在尝试根据深度控制显示顺序。例如,我有一个名为'Cat'的类别。它有两个子类别,分别叫做“Sub Cat 1”和“Sub Cat 2”。是否可以按显示顺序和深度对子类别进行排序?因此,订单将根据显示顺序为“Sub Cat 2”,然后是“Sub Cat 1”。 我希望能够根据深度和显示顺序中的位置来控制类别的顺序。

这是我的问题:

DECLARE @CategoryID INT; 
DECLARE @ExcludeInactive BIT; 

SET @CategoryID = 2; 
SET @ExcludeInactive = 0;

Declare @Categories Table
(
    ID INT,
    Name VARCHAR(500),
    ParentID INT,
    Depth INT, 
    Active BIT,
    DisplayOrder INT
);

INSERT INTO @Categories
SELECT 2, 'Main', 0, 0, 1, 0
UNION ALL
SELECT 6, 'Cat', 2, 0, 1, 0
UNION ALL
SELECT 13, 'Sub Cat 1', 6, 1, 1, 2
UNION ALL
SELECT 14, 'Sub Cat 2', 6, 1, 1,    1
UNION ALL
SELECT 5, 'Cat 2', 2,0, 1, 0
UNION ALL
SELECT 15, 'Sub Cat 1', 5, 1, 1, 2
UNION ALL
SELECT 16, 'Sub Cat 2', 5, 1, 1, 1;

WITH Tree (ID, Name, ParentID, Depth, Sort, Active, DisplayOrder) AS 
( 
    SELECT ID, Name, ParentID, 0 AS Depth, CONVERT(varchar(255), Name) AS Sort, Active,     DisplayOrder         
    FROM @Categories 
    WHERE ParentID = @CategoryID 
    UNION ALL 
    SELECT CT.ID, CT.Name, CT.ParentID, Parent.Depth + 1 AS Depth, 
    CONVERT(varchar(255), Parent.Sort + ' > ' + CT.Name) AS Sort, CT.Active, CT.DisplayOrder 
    FROM @Categories CT 
    INNER JOIN Tree as Parent ON Parent.ID = CT.ParentID WHERE (@ExcludeInactive = 0  OR (CT.Active = 1 ))   
) 


SELECT ID, Name, ParentID, Depth, Sort, Active, DisplayOrder FROM Tree ORDER BY SORT

当前输出:

ID  Name       ParentID   Depth  Sort             Active    DisplayOrder
6   Cat        2          0      Cat                  1         2
13  Sub Cat 1  6          1      Cat > Sub Cat 1      1         2
14  Sub Cat 2  6          1      Cat > Sub Cat 2      1         1
5   Cat 2      2          0      Cat 2                1         1
15  Sub Cat 1  5          1      Cat 2 > Sub Cat 1    1         2
16  Sub Cat 2  5          1      Cat 2 > Sub Cat 2    1         1

期望输出:

ID  Name       ParentID   Depth  Sort             Active    DisplayOrder
5   Cat 2      2          0      Cat 2                1         1
16  Sub Cat 2  5          1      Cat 2 > Sub Cat 2    1         1
15  Sub Cat 1  5          1      Cat 2 > Sub Cat 1    1         2
6   Cat        2          0      Cat                  1         2
14  Sub Cat 2  6          1      Cat > Sub Cat 2      1         1
13  Sub Cat 1  6          1      Cat > Sub Cat 1      1         2

1 个答案:

答案 0 :(得分:0)

这可能是一种更优雅的方式,但您可以执行以下操作:

DECLARE @CategoryID INT; 
DECLARE @ExcludeInactive BIT; 

SET @CategoryID = 2; 
SET @ExcludeInactive = 0;

Declare @Categories Table
(
    ID INT,
    Name VARCHAR(500),
    ParentID INT,
    Depth INT, 
    Active BIT,
    DisplayOrder INT
);

INSERT INTO @Categories
SELECT 2, 'Main', 0, 0, 1, 0
UNION
SELECT 6, 'Cat', 2, 0, 1, 0
UNION
SELECT 13, 'Sub Cat 1', 6, 1, 1, 2
UNION
SELECT 14, 'Sub Cat 2', 6, 1, 1,    1
UNION
SELECT 5, 'Cat 2', 2,0, 1, 0
UNION
SELECT 15, 'Sub Cat 1', 5, 1, 1, 2
UNION
SELECT 16, 'Sub Cat 2', 5, 1, 1, 1;

WITH Tree (ID, Name, ParentID, Depth, Sort, Active, DisplayOrder) AS 
( 
    SELECT ID, Name, ParentID, 0 AS Depth, CONVERT(varchar(255), Name) AS Sort, Active,     DisplayOrder         
    FROM @Categories 
    WHERE ParentID = @CategoryID 
    UNION  
    SELECT CT.ID, CT.Name, CT.ParentID, Parent.Depth + 1 AS Depth, 
    CONVERT(varchar(255), Parent.Sort + ' > ' + CT.Name) AS Sort, CT.Active, CT.DisplayOrder 
    FROM @Categories CT 
    INNER JOIN Tree as Parent ON Parent.ID = CT.ParentID WHERE (@ExcludeInactive = 0  OR (CT.Active = 1 ))   
) 

SELECT ID, Name, ParentID, Depth, Sort, Active, DisplayOrder 
FROM Tree 
ORDER BY SUBSTRING(Sort,1,CHARINDEX(' >',Sort+' >')) DESC, DisplayOrder

请注意,所有这些UNIONS都应该是ALL,但由于防火墙怪癖,我无法发布这些内容。