Order child items in a certain order in a multi-level hierarchy query in SQL Server 2012
我在 SQL Server 2012 中有一个名为
我尝试过的示例数据和查询的情况演示在此问题的 SQL Fiddle 中。
我正在尝试获取最顶层项目的完整层次结构,以便满足以下
我尝试过的查询达到了要求#1,但没有达到要求#2。
问题
除了要求 #1 之外,我如何使用现有的递归查询来实现要求 #2?我不能简单地按 PathStr、CreateDate 排序,因为在我的多级层次结构中没有两条路径是相同的。
架构和示例数据创建查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | CREATE TABLE Items ( ItemId int PRIMARY KEY, ParentId int, CreateDate datetime ); INSERT Items VALUES (44129, 429965, CONVERT(datetime, '2016-01-01 17:30:55.760', 121)), (61291, 203905, CONVERT(datetime, '2016-01-02 20:18:35.770', 121)), (157898, 335625, CONVERT(datetime, '2016-01-01 00:00:06.420', 121)), (191951, 778472, CONVERT(datetime, '2016-01-01 00:00:01.400', 121)), (203905, 960767, CONVERT(datetime, '2016-01-01 00:00:01.310', 121)), (265468, 429965, CONVERT(datetime, '2016-05-01 06:07:26.690', 121)), (268246, 265468, CONVERT(datetime, '2016-10-06 13:41:55.990', 121)), (283015, 394157, CONVERT(datetime, '2017-12-03 01:58:08.710', 121)), (299356, 443367, CONVERT(datetime, '2016-01-01 00:00:01.400', 121)), (335625, 894441, CONVERT(datetime, '2016-11-06 21:27:00.270', 121)), (338413, 968392, CONVERT(datetime, '2016-11-21 07:15:48.010', 121)), (394157, 785375, CONVERT(datetime, '2016-05-19 09:19:28.500', 121)), (397189, 894441, CONVERT(datetime, '2016-01-01 13:34:03.980', 121)), (404536, 894441, CONVERT(datetime, '2016-01-01 00:00:16.850', 121)), (429965, 0, CONVERT(datetime, '2016-01-01 00:00:06.090', 121)), (439536, 968392, CONVERT(datetime, '2017-03-25 23:51:48.570', 121)), (443367, 191951, CONVERT(datetime, '2016-01-01 00:00:01.090', 121)), (778472, 394157, CONVERT(datetime, '2016-01-02 20:43:59.760', 121)), (785375, 910250, CONVERT(datetime, '2017-10-19 03:59:14.950', 121)), (894441, 265468, CONVERT(datetime, '2016-01-01 00:00:08.600', 121)), (910250, 268246, CONVERT(datetime, '2016-07-21 00:43:47.420', 121)), (927248, 785375, CONVERT(datetime, '2017-02-13 04:19:46.340', 121)), (960767, 335625, CONVERT(datetime, '2016-01-01 00:00:01.960', 121)), (968392, 785375, CONVERT(datetime, '2017-09-10 02:15:25.780', 121)) |
我尝试过的查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | WITH x (ItemId, ParentId, PathStr, CreateDate) AS (SELECT ItemId, 0 AS ParentId, CAST(ItemId AS varchar(max)) AS Pathstr, CreateDate FROM Items WHERE ItemId = 429965 UNION ALL --get children for each parent ( c is for child table and x is for parent table) SELECT i.ItemId, i.ParentId, x.PathStr + '-' + CAST(i.ItemId AS varchar(max)), i.CreateDate FROM Items i INNER JOIN x ON x.ItemId = i.ParentId) SELECT *, ROW_NUMBER() OVER (ORDER BY PathStr) AS Position FROM x; |
在上述查询中,
你很接近...
我添加了一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | WITH x (ItemId, ParentId, PathStr, CreateDate,Step) AS (SELECT ItemId, 0 AS ParentId, CAST(ItemId AS varchar(max)) AS Pathstr, CreateDate, 1 AS Step FROM Items WHERE ItemId = 429965 UNION ALL --get children for each parent ( c is for child table and x is for parent table) SELECT i.ItemId, i.ParentId, x.PathStr + '-' + CAST(i.ItemId AS varchar(max)), i.CreateDate, x.Step+1 FROM Items i INNER JOIN x ON x.ItemId = i.ParentId) SELECT *, ROW_NUMBER() OVER (ORDER BY PathStr) AS Position, ROW_NUMBER() OVER (ORDER BY CreateDate) AS DatePosition FROM x ORDER BY Step,DatePosition; |
更新:线程讨论...
试试这个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | WITH x (ItemId, ParentId, PathStr,CreateDate,Step) AS (SELECT ItemId, 0 AS ParentId, CAST(REPLACE(STR(ItemId,9),' ','0') AS VARCHAR(MAX)) AS PathStr, CreateDate, 1 AS Step FROM Items WHERE ItemId = 429965 UNION ALL --get children for each parent ( i is for child table and x is for parent table) SELECT i.ItemId, i.ParentId, CAST(x.PathStr + '-' + REPLACE(STR(i.SortNmbr,3),' ','0') AS VARCHAR(MAX)) + '-' + CAST(REPLACE(STR(i.ItemId,9),' ','0') AS VARCHAR(MAX)), i.CreateDate, x.Step+1 FROM x CROSS APPLY(SELECT *, ROW_NUMBER() OVER(ORDER BY CreateDate) AS SortNmbr FROM Items WHERE Items.ParentId=x.ItemId) AS i ) SELECT * FROM x ORDER BY PathStr; |
如果你想订购一个递归 cte 的结果,你必须在你的
我使用
我的填充允许 ItemId 为