【问题标题】:SQL Parent Child Tree Sort BY DEPTH and Display OrderSQL 父子树按深度排序和显示顺序
【发布时间】:2013-07-13 21:43:07
【问题描述】:

我有一个创建类别层次结构的查询。它工作得很好。现在我正在尝试根据深度控制显示顺序。例如,我有一个名为“猫”的类别。它有两个子类别,称为“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

【问题讨论】:

  • 问题:为什么DECLARE @CategoryID INT;是两次?
  • 很抱歉。它已被删除。
  • 想要的输出是什么?

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


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

【讨论】:

  • 无论哪种方式,这种排序方式都不会使排序字段保持正确的顺序。
  • 更新的问题有帮助,是 Cat 2 把事情搞砸了。
  • 这适用于子类别,但我不适用于类别。我已经更新了当前/期望的输出。
  • 逻辑不明白,你要大类上面的子类按显示顺序排序,你要大类按什么排序?
  • 我更新了所需的输出,我希望这是有道理的。我想要基于深度的类别顺序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-29
  • 2014-04-01
  • 2018-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多