Sql 如何按层次对行进行排序
我有一个具有层次结构、父子关系的表,并希望按该层次结构对其进行排序。表为:Sql 如何按层次对行进行排序,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个具有层次结构、父子关系的表,并希望按该层次结构对其进行排序。表为: id|parent|type -------------- 1 |0 |1 2 |0 |1 3 |0 |1 4 |0 |2 5 |0 |2 6 |2 |2 7 |3 |2 因此,我希望: id|parent|type -------------- 1 |0 |1 2 |0 |1 6 |2 |2 3 |0 |1 7 |3 |2
id|parent|type
--------------
1 |0 |1
2 |0 |1
3 |0 |1
4 |0 |2
5 |0 |2
6 |2 |2
7 |3 |2
因此,我希望:
id|parent|type
--------------
1 |0 |1
2 |0 |1
6 |2 |2
3 |0 |1
7 |3 |2
4 |0 |2
5 |0 |2
所以我想得到一个类似于树视图的东西,其中类型1首先排序,类型2最后排序
现在我尝试使用递归,但顺序错误:
with cte as
(
select id, parent, type from tbl where id=1
union all
select id, parent, type,
ROW_NUMBER()over(
order by
(case when t.type = 1 then 1
when t.type = 2 then 2
else 1000
end) as rn
from tbl t
inner join cte c on c.id=t.parent
)
select * from cte
order by rn
如何执行此操作?可以使用以下递归CTE执行:
WITH cte AS (
SELECT *,
CAST(ROW_NUMBER() OVER(ORDER BY id) AS REAL) rn,
1 level
FROM tbl
WHERE parent = 0
UNION ALL
SELECT t2.*,
cte.rn + (CAST(ROW_NUMBER() OVER(ORDER BY t2.id) AS REAL) / POWER(10, cte.level)) rn,
cte.level + 1 level
FROM tbl t2 INNER JOIN cte
ON t2.parent = cte.id
)
SELECT id, parent, type
FROM cte
ORDER BY rn
请参见更复杂的示例数据(更深层的层次结构,“无序的父子id”)使用order by with cte很简单,而不是测试递归关系
DECLARE @Data table (Id int identity(1,1) primary key, Parent int, Type int)
INSERT @Data VALUES
(0, 1),
(0, 1),
(0, 1),
(0, 2),
(0, 2),
(2, 2),
(3, 2)
SELECT * FROM @Data
;WITH level AS
(
-- The root, build the hierarchy by /{Type}.{Id}/, where Type is important then Id
SELECT *, -- 0 AS Level,
'/' + CONVERT(varchar(max), Type + 0.1 * Id) + '/' AS Ordering
FROM @Data
WHERE Parent = 0
UNION ALL
-- Connect the parent with appending the hierarchy
SELECT d.*, -- c.Level + 1,
c.Ordering + CONVERT(varchar(max), d.Type + 0.1 * d.Id) + '/'
FROM @Data d INNER JOIN level c ON d.Parent = c.Id
)
SELECT Id, Parent, Type FROM level
ORDER BY CAST(Ordering as hierarchyid) -- The key part to convert data type
Connect By是您最好的朋友,如果您想在@istovatis创建这样一个树型表示,它真的很酷,但我使用的是MS Sql Server。您能解释一下对于4和5这样的值,应该如何解释
type=2
?例如,为什么你把它们放在6之后,而不是之前?为什么他们有这个类型
值,首先…你能发布你的小提琴吗?@RogerWolf我有对象类型(type1,type2,等等),type2(和3)总是type1的子对象,但是type1的对象也可以有type1的子对象。如文件夹和文件。将失败,除非数据总是那么简单。例如,超过1个嵌套级别将破坏它。这很好,但有一个细节,id可能比父id大。@Gleb-modified answer,将适用于所有更深层次,“无序的父-子id”,请参阅fiddle。这几乎是我需要的,谢谢。但还有一个问题,现在层次结构是正确的,但是类型3和类型4的对象位于类型1和类型2的对象之上。type1和type2的id也比Type3和type4小。我该怎么解决这个问题?@Gleb很高兴有更多的数据来测试你的问题。通过乘法解决了这个问题。(当v.type='typ1'时为-0.1,当v.type='type2'时为-0.1,否则为0.1结束时为-0.1)*r.id)+'/'。非常感谢。
DECLARE @Data table (Id int identity(1,1) primary key, Parent int, Type int)
INSERT @Data VALUES
(0, 1),
(0, 1),
(0, 1),
(0, 2),
(0, 2),
(2, 2),
(3, 2)
SELECT * FROM @Data
;WITH level AS
(
-- The root, build the hierarchy by /{Type}.{Id}/, where Type is important then Id
SELECT *, -- 0 AS Level,
'/' + CONVERT(varchar(max), Type + 0.1 * Id) + '/' AS Ordering
FROM @Data
WHERE Parent = 0
UNION ALL
-- Connect the parent with appending the hierarchy
SELECT d.*, -- c.Level + 1,
c.Ordering + CONVERT(varchar(max), d.Type + 0.1 * d.Id) + '/'
FROM @Data d INNER JOIN level c ON d.Parent = c.Id
)
SELECT Id, Parent, Type FROM level
ORDER BY CAST(Ordering as hierarchyid) -- The key part to convert data type