层次结构/树-将所有字符串都放入根目录

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

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

所以,在S中,我们有:

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

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

“节点1>节点2>节点3”(对于子节点/叶子节点3)

““节点10>节点20”(对于子节点/叶子节点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
sql sql-server tsql
1个回答
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。顺便说一下,您正在[寻找]那是什么,因为它可以让您回答“此行的子代是什么?”类型的问题?或“该行的血统中有哪些行?”非常容易(即,无需动态计算整个层次结构)。

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