我在SQL Server中有一个表myTable,如下所示:

Id ParentId Order
1 1 1
2 2 1
3 3 1
4 1 2
5 1 1
6 1 3
7 4 1
8 2 2
9 2 1
100 3 1
10 10 1
194 10 1
295 194 1
205 194 2
215 194 3
322 10 2
404 10 3
435 10 4
507 10 5
206 10 6
330 10 7
425 10 8
428 10 9
488 10 10
432 10 11
633 10 12

我希望我的存储过程返回给定ParentId的输出,其中所有Id及其子对象按Order排序.

上表所需结果的示例:

测试ParentId=1应返回:

Id ParentId Order
1 1 1
5 1 1
4 1 2
7 4 1
6 1 3

测试ParentId=4应返回--Testing that even when a 101 is not a 100 of it self the lineage in correct order is produced

Id ParentId Order
4 1 2
7 4 1

测试ParentId=2应返回:

Id ParentId Order
2 2 1
9 2 1
8 2 2

测试ParentId=3应返回:

Id ParentId Order
3 3 1
100 3 1

测试ParentId=10应该返回(这是一个棘手的问题):

Id ParentId Order
10 10 1
194 10 1
295 194 1
205 194 2
215 194 3
322 10 2
404 10 3
435 10 4
507 10 5
206 10 6
330 10 7
425 10 8
428 10 9
488 10 10
432 10 11
633 10 12

我用以下代码成功地获得了给定ParentIdId,并能够递归地对IdId进行排序:

DECLARE @myTable TABLE (Id INT, ParentID INT, [Order] INT)

INSERT INTO @myTable 
VALUES
(1,1,1),
(2,2,2),
(3,3,3),
(4,1,2),
(5,1,1),
(6,1,3),
(7,4,1),
(8,2,2),
(9,2,1),
(100,3,1),
(10,10,1),
(194,10,1),
(295,194,1),
(205,194,2),
(322,10,2),
(215,194,3),
(404,10,3),
(435,10,4),
(507,10,5),
(206,10,6),
(330,10,7),
(425,10,8),
(428,10,9),
(488,10,10),
(432,10,11),
(633,10,12)


IF OBJECT_ID(N'tempdb..#myTable') IS NOT NULL
BEGIN
    DROP TABLE #myTable
END

SELECT * 
INTO #myTable 
FROM @myTable;

WITH ChildHierarchy AS 
(
    -- Base query: find the direct children of the given ParentId
    SELECT 
        Id, ParentId, [Order], 0 AS HierarchyLevel, 
        CAST([Order] AS VARCHAR(MAX)) AS SortPath
    FROM 
        #myTable
    WHERE 
        ParentId = 1 AND Id != 1

    UNION ALL

    -- Recursive query: find the children of each child
    SELECT 
        O.Id, O.ParentId, O.[Order], HierarchyLevel + 1, 
        CAST(ChildHierarchy.SortPath + '.' + CAST(O.[Order] AS VARCHAR(MAX)) AS VARCHAR(MAX))
    FROM 
        #myTable O
    INNER JOIN 
        ChildHierarchy ON O.ParentId = ChildHierarchy.Id
)
SELECT * 
FROM 
    (SELECT 
         Id, ParentId, [Order], CAST(0 AS varchar) AS HierarchyLevel, 
         CAST(0 AS varchar) AS SortPath 
     FROM 
         #myTable 
     WHERE 
         Id = 1

     UNION
     
     SELECT * 
         FROM ChildHierarchy) AS X
     ORDER BY 
    [Order] ASC, X.SortPath ASC

All the test produce the write order except Test ParentId = 10 gives: enter image description here

在@MyTable中,每行只有一个层次 struct 级别(即没有父代的子代将位于另一列的行上)

感谢你们在这方面的任何帮助.

推荐答案

如果SortPath列的类型无关紧要,则可以使用varinary而不是varchar.这将有助于正确地对其进行分类.

DECLARE @root INT
SET @root = 10;

WITH ChildHierarchy AS 
(
    -- Base query: find the direct children of the given ParentId
    SELECT 
        Id, ParentId, [Order], 0 AS HierarchyLevel, 
        CAST([Order] AS VARBINARY(MAX)) AS SortPath
    FROM 
        #myTable
    WHERE 
        ParentId = @root AND Id != @root

    UNION ALL

    -- Recursive query: find the children of each child
    SELECT 
        O.Id, O.ParentId, O.[Order], HierarchyLevel + 1, 
        ChildHierarchy.SortPath + CAST(o.[Order] AS BINARY(2))
    FROM 
        #myTable O
    INNER JOIN 
        ChildHierarchy ON O.ParentId = ChildHierarchy.Id
)
SELECT * 
FROM 
    (SELECT * 
     FROM ChildHierarchy
     UNION
     SELECT 
         Id, ParentId, [Order], CAST(0 AS varchar) AS HierarchyLevel, 
         CAST(0 AS VARBINARY) AS SortPath 
     FROM 
         #myTable 
     WHERE 
         Id = @root) AS X
ORDER BY 
   X.[SortPath] ASC

结果将是这样的:

enter image description here

Sql相关问答推荐

PostgreSQL:获取每家店铺收入最高的员工

如何在PostgreSQL中同时为id s列表执行多个update语句?'

Group By子句返回太多行

从列的不同值创建列

使用来自不同深度的嵌套组的值执行计算的干净方法?

在Postgres中实现合并功能的干净方法,因为当目标/源不匹配时

如何在SQL中按每个子组的顺序更新数据?

PostgreSQL:使用JSONB中的字段使用jsonb_to_Records()填充记录

将日期时间转换为日期格式

如何简化此PostgreSQL查询以计算平均值?

如何用SQL组合客户拥有的产品

PostgreSQL:从多个字段收集特定指标的最后一个条目

Oracle SQL:通过将日期与另一个表行进行比较来 Select 值

snowflake中的动态文件名生成

更新之前如何获得价值

oracle中多行的跨日期范围的交集

PlSql 陷入死循环

使用标准SQL 触发更新当前日期

如何找到特定时间间隔内的最大和最小日期?

在 MindsDB SQL 编辑器中运行 PostgreSQL 条目 ID 时出现未知 Select 目标错误