层次结构/树 - 将所有字符串都添加到root

时间:2015-08-06 16:17:12

标签: sql sql-server tsql

假设我在下面有这个表T,它通过存储父/子对来定义/存储树结构。这些值是整数。在另一个表S中说,我将每个ID /值映射到一个字符串。

所以...让我们在S说:

 Table S
 ID     Name 
 90     "node 90"
 301    "node 301"  
 etc. (even though the real names are different) 

是否可以在T中添加计算列,该计算列为每个子节点提供路径的文本表示,一直到树的根,如附加形式,例如

&#34;节点1&gt; <节点2>节点3&#34; (对于子/叶节点3)

&#34;节点10&gt;节点20&#34; (对于子/叶节点20)

如果通过计算列无法实现,那么我可以使用常规列和该列的一次性更新吗?我在考虑一些递归的CTE,但是我无法理解它(现在)。

Table T   
ParentEventID   ChildEventID
90  301
90  302
90  303
90  304
90  305
90  306
90  307
301 401
301 402
302 403
302 404
302 405
302 406
302 407
303 408
304 409
304 410
304 411
304 412
304 413
304 414
305 415
305 416
305 417
305 418
306 419
306 420
306 421
306 422
307 423
307 424
307 425
307 426
307 427
403 501
403 502
403 503
403 504
403 505
404 506
404 507
404 508
404 509
404 510
405 511
405 512
405 513
405 514
405 515
406 516
406 517
406 518
406 519
406 520
407 521
407 522
407 523
407 524
407 525
415 526
415 527
415 528
415 529
415 530
416 531
416 532
416 533
416 534
416 535
417 536
417 537
417 538
417 539
417 540
418 541
418 542
418 543
418 544
418 545
420 546
420 547
420 548
420 549
420 550
421 551
421 552
421 553
421 554
421 555
422 556
422 557
422 558
422 559
422 560

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

这是我想出的:

WITH cte AS (
    SELECT * FROM (VALUES
        (90, 301),
        (90, 302),
        (90, 303),
        (90, 304),
        (90, 305),
        (90, 306),
        (90, 307),
        (301,401),
        (301,402),
        (302,403),
        (302,404),
        (302,405),
        (302,406),
        (302,407),
        (303,408),
        (304,409),
        (304,410),
        (304,411),
        (304,412),
        (304,413),
        (304,414),
        (305,415),
        (305,416),
        (305,417),
        (305,418),
        (306,419),
        (306,420),
        (306,421),
        (306,422),
        (307,423),
        (307,424),
        (307,425),
        (307,426),
        (307,427),
        (403,501),
        (403,502),
        (403,503),
        (403,504),
        (403,505),
        (404,506),
        (404,507),
        (404,508),
        (404,509),
        (404,510),
        (405,511),
        (405,512),
        (405,513),
        (405,514),
        (405,515),
        (406,516),
        (406,517),
        (406,518),
        (406,519),
        (406,520),
        (407,521),
        (407,522),
        (407,523),
        (407,524),
        (407,525),
        (415,526),
        (415,527),
        (415,528),
        (415,529),
        (415,530),
        (416,531),
        (416,532),
        (416,533),
        (416,534),
        (416,535),
        (417,536),
        (417,537),
        (417,538),
        (417,539),
        (417,540),
        (418,541),
        (418,542),
        (418,543),
        (418,544),
        (418,545),
        (420,546),
        (420,547),
        (420,548),
        (420,549),
        (420,550),
        (421,551),
        (421,552),
        (421,553),
        (421,554),
        (421,555),
        (422,556),
        (422,557),
        (422,558),
        (422,559),
        (422,560)
    ) AS x(ParentEventID, ChildEventID)
), rcte AS (
    SELECT DISTINCT NULL AS [ParentEventID], a.[ParentEventID] AS ChildEventID, CONCAT('/', CAST(a.[ParentEventID] AS NVARCHAR(MAX)), '/') AS h
    FROM cte AS a
    WHERE NOT EXISTS (
        SELECT *
        FROM [cte]
        WHERE [cte].[ChildEventID] = a.[ParentEventID]
    )

    UNION ALL

    SELECT child.[ParentEventID], child.[ChildEventID], CONCAT(parent.h, [child].[ChildEventID], '/')
    FROM [cte] AS child
    JOIN rcte AS parent
        ON child.[ParentEventID] = [parent].[ChildEventID]

)
SELECT * FROM rcte

第一个cte只是我公开数据的快捷方式;解决方案的真正含义是rcte。注意,如果您正在寻找的话,h列可立即转换为HierarchyID。顺便说一句,你应该寻找它,因为这样你就可以回答类型的问题&#34;这一行的孩子是什么?&#34;或者&#34;哪一行在这一行的血统中?&#34;非常容易(即无需动态计算整个层次结构)。