按层次结构按级别拆分数据

时间:2018-10-11 09:37:25

标签: sql sql-server sql-server-2017

初始数据示例:

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

在我的初始数据中,我具有element的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     |

我该怎么做?

1 个答案:

答案 0 :(得分:3)

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

它可以像JOIN一样使用,但还可以返回额外的记录来为您提供NULL

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