使用兄弟排序器在父子表中进行深度优先树遍历,以实现总的“排序器”

问题描述 投票:0回答:1

我使用的系统将分层数据存储在父子表(邻接表)中:

代码 家长代码 分拣机 字幕
A (空) 0 ...
B A 0 ...
C A 1 ...
D C 0 ...
E D 0 ...
F C 1 ...
G C 2 ...

Sorter
列确定兄弟姐妹的顺序。代码 D、F、G 是兄弟姐妹(=同一父母的孩子),并且排序器可能会更改,例如如果插入新行并将其放置在最后一个兄弟之前。例如,最后一个兄弟可以是像“其他”这样的类别,当然“其他”始终是最后一个兄弟,即使稍后插入更详细的类别也是如此。

简而言之:树可能会生长和变化。

对于下游系统,我需要这棵树的“定序器” - 一个深度优先的树遍历,枚举从节点 1(第一个根)到最后一个的行。这可以单独在 T-SQL (SQL Server 2016) 中完成吗?

我之前用 CTE 做了一些实验,我成功了,例如制作一个用于计算级别和完整路径的 CTE。但这些数据在兄弟排序器上不受影响;如果第一个和最后一个同级更改位置,级别和完整路径不会更改。定序器必须这样做。

作为后备措施,我设法在 C# 应用程序中的 Infragistics UltraTree 中绘制树,然后递归迭代。这可行,但是是一种非 SQL 方法。 SQL 可以自己完成这项工作吗?

sql-server tsql parent-child common-table-expression
1个回答
0
投票

这可能会帮助您开始:

CREATE TABLE data_table (
    dt_code VARCHAR(2) NOT NULL,
    dt_parent_code VARCHAR(2),
    dt_sorter INT,
);

INSERT data_table VALUES ( 'A', NULL, 0 );
INSERT data_table VALUES ( 'B', 'A',  0 );
INSERT data_table VALUES ( 'C', 'A',  1 );
INSERT data_table VALUES ( 'D', 'C',  0 );
INSERT data_table VALUES ( 'E', 'D',  0 );
INSERT data_table VALUES ( 'F', 'C',  1 );
INSERT data_table VALUES ( 'G', 'C',  2 );

使用 CTE 查询 - 将 WHERE 子句中的 dt_code 设置为要从层次结构中提取的根值...

WITH cte ( code, parent_code, level, path )
AS
(

-- Anchor member ...
SELECT dt_code, dt_parent_code, 1 AS level,
 CAST( dt_sorter AS VARCHAR( MAX ) ) AS path
 FROM data_table
 WHERE dt_code = 'A'

UNION ALL

-- Recursive member ...
SELECT dt_code, dt_parent_code, cte.level + 1 AS level,
 CAST( cte.path + '.' + CAST( dt_sorter AS VARCHAR ) AS VARCHAR( MAX ) ) AS path
FROM data_table, cte
WHERE dt_parent_code = cte.code
)
SELECT code, parent_code, level, path
 FROM cte
 WHERE code = cte.code
 ORDER BY path;

输出:

code    parent_code level   path
----    ----------- -----   ----
A       (null)         1    0
B       A              2    0.0
C       A              2    0.1
D       C              3    0.1.0
E       D              4    0.1.0.0
F       C              3    0.1.1
G       C              3    0.1.2

希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.