4

I have this query that creates a hierarchy of Categories. It works great. Now I'm trying to control the Display order based on the Depth. For example I have a Category Called 'Cat'. It has two sub categories called 'Sub Cat 1' and 'Sub Cat 2'. Is it possible to sort the sub categories by Display Order and Depth? So the order will be ‘Sub Cat 2’ then ‘Sub Cat 1’, based on the display order. I want to be able to control the order of the categories Based on its location in Depth and Display Order.

Here is my query:

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

Current Output:

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

Desired Output:

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
4

1 回答 1

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,但由于防火墙怪癖,我无法发布它们。

于 2013-07-15T21:37:41.387 回答