按层次结构级别拆分数据

Split data by levels in hierarchy

初始数据示例:

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

在我的初始数据中,我有元素的 ID 和他的父 ID。 有些元素有父元素,有些元素没有,有些元素有父元素,他的父元素有父元素。

此层次结构中的最大级别数为 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     |

我该怎么做?

对于一个固定的三个部门,你可以使用CROSS APPLY

它可以像 JOIN 一样使用,但也可以 return 额外的记录来给你 NULLs。

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 从规范化结构(你的起始数据)中受益匪浅。