按显示顺序和 parent id 对列进行排序
order columns by display order and parent id
我有一个数据集,其中有一个行列表,每个行都有一个 ID
、显示 order
和一个可为空的 parentID
。如果他们有的话,我需要将它们按升序排列在 parent 后面。我不知道该怎么做。我正在考虑尝试一些工会,但需要的工会数量不受限制。
ID order parentID
4 1
6 2
5 1 6
1 2 6
7 3 6
77 3
89 1 77
43 4
23 5
2 1 23
3 2 23
只需将您要排序的所有列放在 ORDER BY
子句中:
select parentID, ordering, ID
from mytab
order by parentID, ordering
(我已将 order
重命名为排序,因为 order
是 SQL 关键字)
更新
要将 NULL parentID 移动到底部,如果您的 RDBMS 支持,您可以使用 NULLS LAST
:
select parentID, ordering, ID
from mytab
order by parentID nulls last, ordering
您必须构建一个排序机制,以说明级别之间的排序以及每个级别内的排序。我将向您展示如何使用递归 CTE 执行此操作。
首先,您需要确定要比较的元素数量。在您的 table 中,答案最多为 5,但这可能是任意的。所以我们先查询一下
declare @dyn_ord as int = (select len(MAX(ordering)) from #A)
这会获取位数,在本例中仅为 1。在这里,我使用“#A”作为您的 table 的名称。
接下来,我们用我们想要的字段设置递归 CTE
declare @dyn_ord as int = (select len(MAX(ordering)) from #A)
; with
Parent as (
-- Anchor member definition
select a.Id -- of course show the ID
, a.parentID -- show the parent's ID
, cast(a.ID as varchar(max)) as Path -- this is bonus to help understand recursion
, CAST((REPLACE(STR(ordering,@dyn_ord),' ','0')) AS nvarchar(max)) AS OrderString -- our modified ordering, explanation to follow
from #A a
where a.parentId is null
union all
-- Recursive member definition
select c.Id
, c.parentID
, cast(Path + ' -> ' + cast(c.ID as varchar(max)) as varchar(max)) as Path
, (p.OrderString + '.' + CAST((REPLACE(STR(c.ordering,@dyn_ord),' ','0')) AS nvarchar(max))) AS OrderString
from #A as c
inner join Parent as p
on c.parentID = p.ID
)
SELECT Id
, parentID
, Path
, OrderString
FROM Parent
order by OrderString asc
OrderString 是我们用来订购的机制。在给定级别中,它 (1) 接受排序,(2) 将其转换为字符串,以及 (3) 根据需要填充任何额外的零。如果您尝试比较 1 和 10 之类的顺序,则需要第三步,这并不总能为您提供字符串比较所需的结果。
在递归步骤中,'OrderString' (1) 从父级获取已经存在的顺序,(2) 附加一个句点(不需要但有助于理解顺序),以及 (3) 然后执行与上一段中相同的三个步骤。
我有一个数据集,其中有一个行列表,每个行都有一个 ID
、显示 order
和一个可为空的 parentID
。如果他们有的话,我需要将它们按升序排列在 parent 后面。我不知道该怎么做。我正在考虑尝试一些工会,但需要的工会数量不受限制。
ID order parentID
4 1
6 2
5 1 6
1 2 6
7 3 6
77 3
89 1 77
43 4
23 5
2 1 23
3 2 23
只需将您要排序的所有列放在 ORDER BY
子句中:
select parentID, ordering, ID
from mytab
order by parentID, ordering
(我已将 order
重命名为排序,因为 order
是 SQL 关键字)
更新
要将 NULL parentID 移动到底部,如果您的 RDBMS 支持,您可以使用 NULLS LAST
:
select parentID, ordering, ID
from mytab
order by parentID nulls last, ordering
您必须构建一个排序机制,以说明级别之间的排序以及每个级别内的排序。我将向您展示如何使用递归 CTE 执行此操作。
首先,您需要确定要比较的元素数量。在您的 table 中,答案最多为 5,但这可能是任意的。所以我们先查询一下
declare @dyn_ord as int = (select len(MAX(ordering)) from #A)
这会获取位数,在本例中仅为 1。在这里,我使用“#A”作为您的 table 的名称。
接下来,我们用我们想要的字段设置递归 CTE
declare @dyn_ord as int = (select len(MAX(ordering)) from #A)
; with
Parent as (
-- Anchor member definition
select a.Id -- of course show the ID
, a.parentID -- show the parent's ID
, cast(a.ID as varchar(max)) as Path -- this is bonus to help understand recursion
, CAST((REPLACE(STR(ordering,@dyn_ord),' ','0')) AS nvarchar(max)) AS OrderString -- our modified ordering, explanation to follow
from #A a
where a.parentId is null
union all
-- Recursive member definition
select c.Id
, c.parentID
, cast(Path + ' -> ' + cast(c.ID as varchar(max)) as varchar(max)) as Path
, (p.OrderString + '.' + CAST((REPLACE(STR(c.ordering,@dyn_ord),' ','0')) AS nvarchar(max))) AS OrderString
from #A as c
inner join Parent as p
on c.parentID = p.ID
)
SELECT Id
, parentID
, Path
, OrderString
FROM Parent
order by OrderString asc
OrderString 是我们用来订购的机制。在给定级别中,它 (1) 接受排序,(2) 将其转换为字符串,以及 (3) 根据需要填充任何额外的零。如果您尝试比较 1 和 10 之类的顺序,则需要第三步,这并不总能为您提供字符串比较所需的结果。
在递归步骤中,'OrderString' (1) 从父级获取已经存在的顺序,(2) 附加一个句点(不需要但有助于理解顺序),以及 (3) 然后执行与上一段中相同的三个步骤。