按层次结构检查父编号

时间:2017-04-26 12:44:13

标签: sql-server tsql

我使用的表格为CADIGR,而列DIGR_KEY1始终是该行中的父级号码(父级的DIGR_KEY)。

我必须更新CADIGR DIGR_KEY1(父母号码),但首先我必须检查我是不是用他们父母之一更新孩子。

我真的不知道该怎么做?孩子可以有很多父母,所以必须在整个树上进行检查直到根(DIGR_KEY1 IS NULL)。

只有当该号码不存在作为该子树的父号时,才有可能进行更新。

CREATE TABLE CADIGR
(
DIGR_KEY INT,
DIGR_KEY1 INT
)


INSERT INTO CADIGR (DIGR_KEY, DIGR_KEY1)
VALUES
(1, NULL),
(2,1),
(3,1),
(4,1),
(11,4),
(12,4),
(13,4),
(5,2),
(6,2),
(5,2),
(6,2),
(7,5),
(8,5),
(9,5),
(10,5),
(14,3),
(15,3)

1 个答案:

答案 0 :(得分:2)

您可以使用这样的递归查询,可以使用level对每组子进行操作。

WITH Rec as
(
    SELECT digr_key, digr_key1, 1 AS level
    FROM   CADIGR
    WHERE  digr_key1 is null
    UNION ALL
    SELECT     c.digr_key, c.digr_key1, level = level + 1
    FROM       CADIGR c
    INNER JOIN rec
    ON         c.digr_key1 = rec.digr_key
)
SELECT *
FROM   Rec;
GO
digr_key | digr_key1 | level
-------: | --------: | ----:
       1 |      null |     1
       2 |         1 |     2
       3 |         1 |     2
       4 |         1 |     2
      11 |         4 |     3
      12 |         4 |     3
      13 |         4 |     3
      14 |         3 |     3
      15 |         3 |     3
       5 |         2 |     3
       6 |         2 |     3
       5 |         2 |     3
       6 |         2 |     3
       7 |         5 |     4
       8 |         5 |     4
       9 |         5 |     4
      10 |         5 |     4
       7 |         5 |     4
       8 |         5 |     4
       9 |         5 |     4
      10 |         5 |     4

dbfiddle here

避免重复记录

WITH DistData as
(
    SELECT DISTINCT digr_key, digr_key1
    FROM   CADIGR
)
    , Rec as
    (
        SELECT digr_key, digr_key1, 1 AS level
        FROM   DistData
        WHERE  digr_key1 is null
        UNION ALL
        SELECT     c.digr_key, c.digr_key1, level = level + 1
        FROM       DistData c
        INNER JOIN rec
        ON         c.digr_key1 = rec.digr_key
    )
    SELECT *
    FROM   Rec;
GO
digr_key | digr_key1 | level
-------: | --------: | ----:
       1 |      null |     1
       2 |         1 |     2
       3 |         1 |     2
       4 |         1 |     2
      11 |         4 |     3
      12 |         4 |     3
      13 |         4 |     3
      14 |         3 |     3
      15 |         3 |     3
       5 |         2 |     3
       6 |         2 |     3
       7 |         5 |     4
       8 |         5 |     4
       9 |         5 |     4
      10 |         5 |     4

dbfiddle here