父子树分层顺序

Arc*_*l33 21 sql-server hierarchy order-by sql-server-2008-r2

我必须跟踪 SQL Server 2008 R2 中的数据。SQLFiddle

架构:

创建表 [dbo].[ICFilters](
   [ICFilterID] [int] IDENTITY(1,1) 非空,
   [ParentID] [int] NOT NULL DEFAULT 0,
   [FilterDesc] [varchar](50) NOT NULL,
   [Active] [tinyint] NOT NULL DEFAULT 1,
 约束 [PK_ICFilters] 主键聚集 
 ( [ICFilterID] ASC ) 与 
    PAD_INDEX = 关闭,
    STATISTICS_NORECOMPUTE = 关闭,
    IGNORE_DUP_KEY = 关闭,
    ALLOW_ROW_LOCKS = 开,
    ALLOW_PAGE_LOCKS = 开
 ) 在 [主要]
) 在 [主要]

INSERT INTO [dbo].[ICFilters] (ParentID,FilterDesc,Active)
价值观 
(0,'产品类型',1),
(1,'ProdSubType_1',1),
(1,'ProdSubType_2',1),
(1,'ProdSubType_3',1),
(1,'ProdSubType_4',1),
(2,'PST_1.1',1),
(2,'PST_1.2',1),
(2,'PST_1.3',1),
(2,'PST_1.4',1),
(2,'PST_1.5',1),
(2,'PST_1.6',1),
(2,'PST_1.7',0),
(3,'PST_2.1',1),
(3,'PST_2.2',0),
(3,'PST_2.3',1),
(3,'PST_2.4',1),
(14,'PST_2.2.1',1),
(14,'PST_2.2.2',1),
(14,'PST_2.2.3',1),
(3,'PST_2.8',1)

桌子:

| ICFILTERID | 家长 | 过滤器 | 活跃 |
--------------------------------------------------
| 1 | 0 | 产品类型 | 1 |
| 2 | 1 | ProdSubType_1 | 1 |
| 3 | 1 | ProdSubType_2 | 1 |
| 4 | 1 | ProdSubType_3 | 1 |
| 5 | 1 | ProdSubType_4 | 1 |
| 6 | 2 | PST_1.1 | 1 |
| 7 | 2 | PST_1.2 | 1 |
| 8 | 2 | PST_1.3 | 1 |
| 9 | 2 | PST_1.4 | 1 |
| 10 | 2 | PST_1.5 | 1 |
| 11 | 2 | PST_1.6 | 1 |
| 12 | 2 | PST_1.7 | 0 |
| 13 | 3 | PST_2.1 | 1 |
| 14 | 3 | PST_2.2 | 0 |
| 15 | 3 | PST_2.3 | 1 |
| 16 | 3 | PST_2.4 | 1 |
| 17 | 14 | PST_2.2.1 | 1 |
| 18 | 14 | PST_2.2.2 | 1 |
| 19 | 14 | PST_2.2.3 | 1 |
| 20 | 3 | PST_2.8 | 1 |

每一行都有其父的 ID 和根的parentid = 0. 该FilterDescs为刚刚样本的描述,所以我不能尝试解析那些排序。

问题

是否可以以树状方式选择所有行?如果是这样,如何?当我说“树状”时,我的意思是递归选择父级,然后是所有子级,然后是每个子级的所有子级,依此类推。深度优先树遍历。

我和我的朋友们已经尝试过,但我们没有找到可行的解决方案,但会继续尝试。我对sql相当陌生,所以也许这可以轻松完成,而且我只是让事情变得比必要的更难。

示例(所需)输出:

| ICFILTERID | 家长 | 过滤器 | 活跃 |
--------------------------------------------------
| 1 | 0 | 产品类型 | 1 |
| 2 | 1 | ProdSubType_1 | 1 |
| 6 | 2 | PST_1.1 | 1 |
| 7 | 2 | PST_1.2 | 1 |
| 8 | 2 | PST_1.3 | 1 |
| 9 | 2 | PST_1.4 | 1 |
| 10 | 2 | PST_1.5 | 1 |
| 11 | 2 | PST_1.6 | 1 |
| 12 | 2 | PST_1.7 | 0 |
| 3 | 1 | ProdSubType_2 | 1 |
| 13 | 3 | PST_2.1 | 1 |
| 14 | 3 | PST_2.2 | 0 |
| 17 | 14 | PST_2.2.1 | 1 |
| 18 | 14 | PST_2.2.2 | 1 |
| 19 | 14 | PST_2.2.3 | 1 |
| 15 | 3 | PST_2.3 | 1 |
| 16 | 3 | PST_2.4 | 1 |
| 20 | 3 | PST_2.8 | 1 |
| 4 | 1 | ProdSubType_3 | 1 |
| 5 | 1 | ProdSubType_4 | 1 |

Tra*_*vis 25

好的,足够的脑细胞已经死亡。

SQL小提琴

WITH cte AS
(
  SELECT 
    [ICFilterID], 
    [ParentID],
    [FilterDesc],
    [Active],
    CAST(0 AS varbinary(max)) AS Level
  FROM [dbo].[ICFilters]
  WHERE [ParentID] = 0
  UNION ALL
  SELECT 
    i.[ICFilterID], 
    i.[ParentID],
    i.[FilterDesc],
    i.[Active],  
    Level + CAST(i.[ICFilterID] AS varbinary(max)) AS Level
  FROM [dbo].[ICFilters] i
  INNER JOIN cte c
    ON c.[ICFilterID] = i.[ParentID]
)

SELECT 
  [ICFilterID], 
  [ParentID],
  [FilterDesc],
  [Active]
FROM cte
ORDER BY [Level];
Run Code Online (Sandbox Code Playgroud)

  • 我不相信这是 100% 正确的解决方案。很难,它列出了层次结构中具有正确级别的所有行,它没有按照问题要求的顺序列出它。是否可以根据问题以正确的顺序列出行?这也是我正在寻找的。 (4认同)
  • 这正是我所需要的!我同意太多的脑细胞已经死亡。我是不是不清楚我想要什么?如果是这样,我将编辑问题以供将来参考。我肯定让它变得比需要的更难...... (2认同)
  • +1 但使用 [ICFilterID] [int] IDENTITY(1,1) 进行排序只会在项目以正确的顺序插入时起作用,但 OT 尚未实现其他用于排序的字段 (2认同)