Запрос PostgreSQL WITH RECURSIVE для получения упорядоченной цепочки родитель-потомок по ключу раздела - PullRequest
0 голосов
/ 26 сентября 2018

У меня проблема с написанием сценария sql на PostgreSQL 9.6.6, который упорядочивает шаги в процессе с использованием идентификаторов parent-child шагов, и это группируется / разбивается на идентификаторы процессов.Я не смог найти этот особый случай здесь, поэтому я прошу прощения, если я пропустил его, и прошу вас предоставить мне ссылку на решение в комментариях.

Случай: у меня есть таблица, которая выглядит так:

processID | stepID | parentID
     1         1          NULL
     1         3           5
     1         2           4
     1         4           3
     1         5           1
     2         1          NULL
     2         3           5
     2         2           4
     2         4           3
     2         5           1

Теперь мне нужно упорядочить шаги, начиная с шага, где parentID равен NULL для каждого processID.

Примечание: я не могу просто заказать StepID или parentID как новые шаги, которые я добавляюв течение всего процесса получите более высокий stepID, чем последний шаг процесса (непрерывный генерирующий суррогатный ключ).

Мне нужно заказать шаги для каждого processID, чтобы я получил следующий вывод:

processID | stepID | parentID
     1         1          NULL
     1         5           1
     1         3           5
     1         4           3
     1         2           4
     2         1          NULL
     2         5           1
     2         3           5
     2         4           3
     2         2           4

Я пытался сделать это с помощью функции CTE WITH RECURSIVE:

    WITH RECURSIVE
starting (processID,stepID, parentID) AS
  (
    SELECT b.processID,b.stepID, b.parentID
    FROM process b
    WHERE b.parentID ISNULL
  ),
  descendants (processID,stepID, parentID) AS
  (
    SELECT b.processID,b.stepID, b.stepparentID
    FROM starting b
    UNION ALL
    SELECT b.processID,b.stepID, b.parentID
    FROM process b

    JOIN descendants AS c ON b.parentID = c.stepID
)
SELECT * FROM descendants

Результат не тот, который я ищу.Поскольку у нас есть сотни процессов, я получаю список, в котором первыми записями являются разные идентификаторы процессов, которые имеют значение NULL в качестве parentID.

Полагаю, мне снова придется рекурсивно весь сценарий с идентификатором процесса, но я не имеюидея как.

Спасибо за вашу помощь!

1 Ответ

0 голосов
/ 26 сентября 2018

Вы должны рассчитать уровень каждого шага:

with recursive starting as (
    select processid, stepid, parentid, 0 as level
    from process
    where parentid is null
union all
    select p.processid, p.stepid, p.parentid, level+ 1
    from starting s
    join process p on s.stepid = p.parentid and s.processid = p.processid
)
select *
from starting
order by processid, level

 processid | stepid | parentid | level 
-----------+--------+----------+-------
         1 |      1 |          |     0
         1 |      5 |        1 |     1
         1 |      3 |        5 |     2
         1 |      4 |        3 |     3
         1 |      2 |        4 |     4
         2 |      1 |          |     0
         2 |      5 |        1 |     1
         2 |      3 |        5 |     2
         2 |      4 |        3 |     3
         2 |      2 |        4 |     4
(10 rows)   

Конечно, вы можете пропустить последний столбец в конечном выборе, если вам это не нужно.

...