2013-07-15 41 views
4

我有這個查詢創建類別的層次結構。它效果很好。現在我試圖根據深度控制顯示順序。例如,我有一個類別稱爲'貓'。它有兩個子類別,分別稱爲「小貓1」和「小貓2」。是否可以按顯示順序和深度對子類別進行排序?因此,根據顯示順序,訂單將是'Sub Cat 2',然後是'Sub Cat 1'。 我希望能夠根據深度和顯示順序中的位置來控制類別的順序。SQL父子樹排序深度和顯示順序

這裏是我的查詢:

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 
+0

問:爲什麼'DECLARE @CategoryID INT''兩次? –

+0

對不起。它已被刪除。 – user2585080

+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但我無法張貼他們由於防火牆的怪癖。

+0

順序應該是其他方式(基於最新編輯)。 –

+0

無論採用哪種方式,此順序都不會按正確順序保留排序字段。 – user2585080

+0

更新的問題可以幫助解決問題,這是Cat 2的功能。 –