Разделить данные по уровням в иерархии - PullRequest
0 голосов
/ 11 октября 2018

Пример исходных данных:

| ID   |  ParentID  |
|------|------------|
|  1   |    NULL    |
|  2   |     1      |
|  3   |     1      |
|  4   |     2      |
|  5   |    NULL    |
|  6   |     2      |
|  7   |     3      |

В моих исходных данных у меня есть идентификатор элемента и его родительский идентификатор.У некоторых элементов есть родитель, у некоторых нет, у некоторых есть родитель, а у его родителя есть родитель.

Максимальное количество уровней в этой иерархии - 3.

Мне нужно получить эту иерархию поуровни.

Lvl 1 - элементы без родителей Lvl 2 - элементы с родителями, у которых нет родителей Lvl 3 - элементы с родителями, у которых тоже есть родители.

Ожидаемый результат выглядит следующим образом:

| Lvl1  |   Lvl2   |   Lvl3   |
|-------|----------|----------|
|  1    |   NULL   |   NULL   |
|  1    |    2     |   NULL   |
|  1    |    3     |   NULL   |
|  1    |    2     |    4     |
|  5    |   NULL   |   NULL   |
|  1    |    2     |    6     |
|  1    |    3     |    7     |

Как я могу это сделать?

1 Ответ

0 голосов
/ 11 октября 2018

Для фиксированного коэффициента три можно использовать CROSS APPLY.

. Можно использовать как JOIN, но также возвращать дополнительные записи, чтобы получить NULL s.

SELECT
  Lvl1.ID   AS lvl1,
  Lvl2.ID   AS lvl2,
  Lvl3.ID   AS lvl3
FROM
  initial_data   AS Lvl1
CROSS APPLY
(
   SELECT ID FROM initial_data WHERE ParentID = Lvl1.ID
   UNION ALL
   SELECT NULL AS ID
)
  AS Lvl2
CROSS APPLY
(
   SELECT ID FROM initial_data WHERE ParentID = Lvl2.ID
   UNION ALL
   SELECT NULL AS ID
)
  AS Lvl3
WHERE
  Lvl1.ParentID IS NULL
ORDER BY
  Lvl1.ID,
  Lvl2.ID,
  Lvl3.ID

Но, согласно моему комментарию, это часто признак того, что вы идете по не-sql маршруту.Начать с этого может быть легче, но позже это перевернет и укусит вас, потому что SQL чрезвычайно выигрывает от нормализованных структур (ваших исходных данных).

...