t-sql запрос для рекурсивного обновления данных - PullRequest
0 голосов
/ 30 января 2019
Max_ID     Second_Max_ID   Cumulative_ID
173          97             ,97
174          173            ,97,173
...          ...            ...

Мне нужно написать запрос для вычисления совокупного идентификатора.Может кто-нибудь помочь?Это временная таблица с 3 столбцами (Max_ID, Second_Max_ID, Cumulative_ID), где у меня есть только значения Max_ID и Second_Max_ID в таблице, и мне нужно вычислить Cumulative_ID для каждой строки в той же временной таблице.

Я использовалзапрос предоставлен shnugo и изменил запрос, как показано ниже -

DECLARE @mockup TABLE(Max_ID INT,Second_Max_ID INT);
INSERT INTO @mockup VALUES
(173 , 97   )
,(174 , 173  );

WITH recCTE AS
(
    SELECT Max_ID
          ,Second_Max_ID
          ,CAST(Second_Max_ID AS VARCHAR(MAX)) AS Cumulative_ID
    FROM @mockup --WHERE Second_Max_ID IS NULL

    UNION ALL
    SELECT m.Max_ID
          ,m.Second_Max_ID
          ,r.Cumulative_ID+','+ cast(m.Second_Max_ID as varchar(max))
    FROM @mockup m 
    INNER JOIN recCTE r ON r.Max_ID=m.Second_Max_ID
)
SELECT * FROM recCTE;

Теперь получаю результат наподобие -

Max_ID  Second_Max_ID   Cumulative_ID
173          97            97
174          173          173
174          173          97,173

Как удалить вторую строку из результата выше?

1 Ответ

0 голосов
/ 30 января 2019

Вы можете попробовать это:

DECLARE @mockup TABLE(Max_ID INT,Second_Max_ID INT);
INSERT INTO @mockup VALUES
 (97   ,NULL  )
,(173 , 97   )
,(174 , 173  )
,(175 , 174  );

WITH recCTE AS
(
    SELECT Max_ID
          ,Second_Max_ID
          ,CAST(Max_ID AS VARCHAR(MAX)) AS Cumulative_ID
    FROM @mockup WHERE Second_Max_ID IS NULL

    UNION ALL
    SELECT m.Max_ID
          ,m.Second_Max_ID
          ,CONCAT(r.Cumulative_ID,',',m.Max_ID)
    FROM @mockup m 
    INNER JOIN recCTE r ON r.Max_ID=m.Second_Max_ID
)
SELECT * FROM recCTE;

Идея - рекурсивный CTE (скорее, итерационный подход).Вы начинаете с одной строки без parent (Second_Max_ID IS NULL).

Это перемещается по списку (скрытый RBAR ) и выполняет конкатенацию на лету .

Вы отмечены v2008 и v2012.Если CONCAT() не работает для вас, вы можете легко использовать простой + с необходимым преобразованием в varchar.

ОБНОВЛЕНИЕ

В этой версии я добавлю счетчик для глубины иерархии:

WITH recCTE AS
(
    SELECT Max_ID
          ,Second_Max_ID
          ,CAST(Max_ID AS VARCHAR(MAX)) AS Cumulative_ID
          ,1 AS HierarchyLevel
    FROM @mockup WHERE Second_Max_ID IS NULL

    UNION ALL
    SELECT m.Max_ID
          ,m.Second_Max_ID
          ,CONCAT(r.Cumulative_ID,',',m.Max_ID)
          ,r.HierarchyLevel+1
    FROM @mockup m 
    INNER JOIN recCTE r ON r.Max_ID=m.Second_Max_ID
)
SELECT * 
FROM recCTE;

Вы можете использовать

  • a WHERE для фильтрации для специального уровня
  • TOP 1 в сочетании с ORDER BY HierachyLevel DESC для получения последнего элемента (с самым длинным путем).

Надеюсь, это поможет!

...