Sql 如何使用traverse CTE生成树路径
假设表中的数据与附件中的一样,没有路径列。 我想使用sql中的traverse CTE生成一个列,如图片中的路径 图片示例: 使用以下方法解决此问题:Sql 如何使用traverse CTE生成树路径,sql,sql-server,Sql,Sql Server,假设表中的数据与附件中的一样,没有路径列。 我想使用sql中的traverse CTE生成一个列,如图片中的路径 图片示例: 使用以下方法解决此问题: WITH recCTE AS ( SELECT id, parentid, id AS original_id, parentid AS original_parentid, name as original_name, 1 AS depth,
WITH recCTE
AS (
SELECT id,
parentid,
id AS original_id,
parentid AS original_parentid,
name as original_name,
1 AS depth,
CAST(name AS VARCHAR(5000)) AS path
FROM yourtable
UNION ALL
SELECT yourtable.id,
yourtable.parentid,
recCTE.original_id,
recCTE.original_parentID,
recCTE.original_name,
recCTE.depth + 1,
CAST(recCTE.path + '-' + yourtable.name as VARCHAR(5000))
FROM recCTE
INNER JOIN yourtable
ON recCTE.parentid = yourtable.id
WHERE depth < 20 /*prevent cycling*/
)
SELECT original_id as id, original_parentid as parentid, original_name as name, depth, path
FROM recCTE t1
WHERE depth = (SELECT max(depth) FROM recCTE WHERE t1.original_id = recCTE.original_id)
CTE由两部分组成:
锚定构件,是表中的第一个选择。这定义了输出中的列和列类型。
从包含它的CTE中选择的递归成员将迭代执行,直到连接失败。
在本例中,我们通过在递归成员中反复将路径连接到名称来捕获路径。我们还跟踪执行了多少次递归,并跟踪当前id和parentid以及原始id和原始parentid,以便在最终SELECT语句中选择它们。试试这个
;with cte(id,parentId,name,path,cnt)
AS
(
select id,parentid,name,cast(name as VARCHAR(1024)) as path, 1 as cnt from test_cte
union all
select a.id,a.parentid,a.name,CAST((a.name + '-' +path ) as VARCHAR(1024)), case when a.parentid is null then 0 else cnt + 1 end as cnt from test_cte a join cte c on c.id = a.parentid where c.cnt is not null
)
select id,parentid,name,path from (select id,parentid,name,path, row_number() over(partition by id order by cnt desc) as rank from cte) a where a.rank = 1 order by 1 asc ;
递归查询recCTE的列路径中的锚点和递归部分之间的类型不匹配。可能需要将该名称字段强制转换为递归成员中的varchar5000。SQL Server在递归语句中对这一点很挑剔。我将更新。您需要castrecte.path+'-'+yourtable.name作为VARCHAR5000Updated谢谢@LONG我总是忘记使用SQL Server。@JNevill,NP xD,很容易忽略这一点似乎没有问题,但一个问题是,它重复自己的行字符两次,就像C-C-B-A重复两次C一样,我想要像C-B-A一样,当您有重复的名称时,它的字符将重复