根据孩子的状态更新家长状态

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

我的数据有分层结构。
每条记录都有一个状态栏。如果设置了这个,我想向上继承它。

我尝试使用 CTE 递归地确定各个孩子的最小状态。如果并非所有子级都具有状态 1,则父级应具有状态 0。如果所有子级都具有状态 1,则父级也应具有状态 1。

这是我的测试数据+ SQL。

DECLARE @data TABLE (
    RowNo INT NOT NULL IDENTITY (1, 1)
  , ID NVARCHAR(15)
  , [ID_Parent] NVARCHAR(15)
  , [Status] INT
);

INSERT INTO @data ([ID], [ID_Parent], [Status])
    VALUES ('1', NULL, 0);
INSERT INTO @data ([ID], [ID_Parent], [Status])
    VALUES ('1.1', '1', 0);
INSERT INTO @data ([ID], [ID_Parent], [Status])
    VALUES ('1.1.1', '1.1', 1);
INSERT INTO @data ([ID], [ID_Parent], [Status])
    VALUES ('1.1.2', '1.1', 1);
INSERT INTO @data ([ID], [ID_Parent], [Status])
    VALUES ('1.2', '1', 1);
INSERT INTO @data ([ID], [ID_Parent], [Status])
    VALUES ('1.3', '1', 1);

SELECT *
  FROM @data

;
WITH C
AS
(SELECT T.RowNo
      , T.ID
      , T.[Status]
      , T.ID AS RootID
      FROM @data T
    UNION ALL
    SELECT T.RowNo
         , T.ID
         , T.[Status]
         , C.RootID
      FROM @data T
           INNER JOIN C
                        ON T.ID_Parent = C.ID)
SELECT T.RowNo
     , T.ID
     , T.ID_Parent
     , T.[Status]
     , S.[MINeveryNode]
  FROM @data T
       INNER JOIN (SELECT RootID
                        , MIN([Status]) AS [MINeveryNode]
             FROM C
            GROUP BY RootID) AS S
                    ON T.Id = S.RootID
 ORDER BY T.RowNo
OPTION (MAXRECURSION 0)
sql sql-server recursion common-table-expression sql-server-2022
1个回答
0
投票

我相信您应该加入

C.ID
而不是
T.ID
。现在应该根据其子项的最低状态,正确地将每条记录与其父项的状态关联起来。

DECLARE @data TABLE (
    RowNo INT NOT NULL IDENTITY (1, 1)
  , ID NVARCHAR(15)
  , [ID_Parent] NVARCHAR(15)
  , [Status] INT
);

INSERT INTO @data ([ID], [ID_Parent], [Status])
    VALUES ('1', NULL, 0);
INSERT INTO @data ([ID], [ID_Parent], [Status])
    VALUES ('1.1', '1', 0);
INSERT INTO @data ([ID], [ID_Parent], [Status])
    VALUES ('1.1.1', '1.1', 1);
INSERT INTO @data ([ID], [ID_Parent], [Status])
    VALUES ('1.1.2', '1.1', 1);
INSERT INTO @data ([ID], [ID_Parent], [Status])
    VALUES ('1.2', '1', 1);
INSERT INTO @data ([ID], [ID_Parent], [Status])
    VALUES ('1.3', '1', 1);

WITH C AS (
    SELECT T.RowNo
         , T.ID
         , T.[Status]
         , T.ID AS RootID
      FROM @data T
    UNION ALL
    SELECT T.RowNo
         , T.ID
         , T.[Status]
         , C.RootID
      FROM @data T
           INNER JOIN C
                        ON T.ID_Parent = C.ID)
SELECT T.RowNo
     , T.ID
     , T.ID_Parent
     , T.[Status]
     , S.[MINeveryNode]
  FROM @data T
       INNER JOIN (SELECT RootID
                        , MIN([Status]) AS [MINeveryNode]
             FROM C
            GROUP BY RootID) AS S
                    ON T.ID = S.RootID
 ORDER BY T.RowNo
OPTION (MAXRECURSION 0);
© www.soinside.com 2019 - 2024. All rights reserved.