Sql 分层CTE,每个级别有额外的排序列

Sql 分层CTE,每个级别有额外的排序列,sql,path,hierarchy,common-table-expression,Sql,Path,Hierarchy,Common Table Expression,CTE对我来说有点陌生,所以我希望有人能帮助我写下下面的一个,它将获取一个类别表,并从中构建一个层次结构以供显示。我知道这类问题一直被问到,但我认为我的排序情况让它有点独特 我希望有很多建议使用HierarchyID,但遗憾的是,这不是一个选项,因为这里有一长串不相关的原因。虽然我提出的解决方案有效,并提供了我期望的数据,但我想知道是否有更好/更优雅的方法来实现这一点 基本要求如下: 类别可以有无限数量的子类别 类别可以是无限多个级别 具有相同父级的类别将根据“排序”字段进行排序。如果一个未指定

CTE对我来说有点陌生,所以我希望有人能帮助我写下下面的一个,它将获取一个类别表,并从中构建一个层次结构以供显示。我知道这类问题一直被问到,但我认为我的排序情况让它有点独特

我希望有很多建议使用HierarchyID,但遗憾的是,这不是一个选项,因为这里有一长串不相关的原因。虽然我提出的解决方案有效,并提供了我期望的数据,但我想知道是否有更好/更优雅的方法来实现这一点

基本要求如下:

  • 类别可以有无限数量的子类别
  • 类别可以是无限多个级别
  • 具有相同父级的类别将根据“排序”字段进行排序。如果一个未指定(默认值为0)或与另一个同级类别相同,则将按字母顺序排序
  • 表定义:

    CREATE TABLE [dbo].[TreeTest]
    (
        [id] [int] NOT NULL,
        [parent] [int] NULL,
        [title] [varchar](50) NOT NULL,
        [sort] [int] NOT NULL
    )
    GO
    
    ALTER TABLE [dbo].[TreeTest] ADD  CONSTRAINT [DF_TreeTest_sort]  DEFAULT ((0)) FOR [sort]
    GO
    
    插入语句:

    INSERT TreeTest(id,parent,title,sort) VALUES('1',NULL,'Parent 1','0')
    INSERT TreeTest(id,parent,title,sort) VALUES('2',NULL,'Parent 2','0')
    INSERT TreeTest(id,parent,title,sort) VALUES('3',NULL,'Parent 3','2')
    INSERT TreeTest(id,parent,title,sort) VALUES('4',NULL,'Parent 4','1')
    INSERT TreeTest(id,parent,title,sort) VALUES('5','1','Child 1a','0')
    INSERT TreeTest(id,parent,title,sort) VALUES('6','2','Child 2a','0')
    INSERT TreeTest(id,parent,title,sort) VALUES('7','3','Child 3a','0')
    INSERT TreeTest(id,parent,title,sort) VALUES('8','1','Child 1b','1')
    INSERT TreeTest(id,parent,title,sort) VALUES('9','1','Child 1c','2')
    INSERT TreeTest(id,parent,title,sort) VALUES('10','1','Child 1d','1')
    INSERT TreeTest(id,parent,title,sort) VALUES('11','6','Child 2a 1','0')
    INSERT TreeTest(id,parent,title,sort) VALUES('12','6','Child 2a 2','1')
    INSERT TreeTest(id,parent,title,sort) VALUES('13','6','Child 2a 3','0')
    INSERT TreeTest(id,parent,title,sort) VALUES('14','6','Child 2a 4','2')
    
    CTE:

    输出(我认为图像是显示输出的最简单方式)


    同样,这是根据我的规范工作的,但我不确定效率,以及是否有更好的方法来做到这一点。当我查看这个执行计划时,似乎最昂贵的部分是排序/索引扫描,但考虑到本例中缺少索引,这似乎是意料之中的。如果有人有任何意见,我们将不胜感激。

    递归CTE几乎是SQL Server中最干净的选项。如果是Oracle,您可以使用CONNECT BY,但鉴于您已经声明不能使用HierarchyID,SQL Server中没有等效项

    order by case when parent=0 then parentid else id end
    

    这里id表示表上的主键

    唯一有效的答案:Try itTry究竟是什么?我已经知道我想出的解决方案非常有效。。。我希望了解这是否是最好的/最优雅的方法…关于level_id_path,pad在其上留下了一些零,因此,例如,数字12不会排序在数字2之前。1, 12, 2; 应该是01,02,12。如果您不确信子节点不会仅停留在十个(可能超过100个)中,请在其左侧填充3个零。与您的逻辑相同,但预期100个子节点非常好,Michael,谢谢!您正在使用哪个数据库引擎?如果您使用的是SQL Server 2008或更高版本,则可能需要检查HierarchyID类型。
    order by case when parent=0 then parentid else id end