我有一个非常庞大的层次结构表格,无法修改。表格中的节点具有
Id
、ParentId
、Level
和一些数据。 Level
表示级别为N
的节点不仅可以是级别为N-1
的子级,还可以是级别为N-2
、N-3
等的子级。好消息是,级别数量有限 - 只有8个级别。级别1位于层次结构的顶部,级别8是其末端。
现在,我需要根据级别的位置对该表进行扁平化处理。结果应该像这样:
Lvl1 Lvl2 Lvl3 ... Lvl8
xxx xxx null xxx
xxx null xxx xxx
xxx null null xxx
xxx xxx xxx xxx
第一步
由于级别数量有限,首先的想法是在ParentId = Id
上多次使用LEFT JOIN
将所有表连接起来。但这会导致级别改变位置,因为可能跳过了第6级,第5级取代了其位置。
第二步 因此,我使用了CASE WHEN
根据行的级别选择值。
-- LEVEL 4
CASE
WHEN lvl6.[Level] = 4 THEN lvl6.Data -- in case levels 6 and 5 were skipped, we can find 4th level data here
WHEN lvl5.[Level] = 4 THEN lvl5.Data
WHEN lvl4.[Level] = 4 THEN lvl4.Data
ELSE NULL
END AS l4Data,
它解决了我的问题,但速度非常慢。
第三步 级别的组合也是有限的(1-2-3-4-5-6-7-8
,1-3-5-6-7-8
等)。因此,我决定使用更多的 LEFT JOIN
将所有级别的组合粘合在一起:
WITH
l7 AS (SELECT * FROM myTable WHERE [Level] = 7),
l6 AS (SELECT * FROM myTable WHERE [Level] = 6),
...
FROM l7
...
LEFT JOIN l6 AS l6_7 ON l7.ParentId = l6_7.Id -- 7-6-5-4-1
LEFT JOIN l5 AS l5_7 ON l6_7.ParentId = l5_7.Id
LEFT JOIN l4 AS l4_7 ON l5_7.ParentId = l4_7.Id
LEFT JOIN l1 AS l1_7 ON l4_7.ParentId = l1_7.Id
然后我使用COALESCE
选择数据:
COALESCE(l3.Data, l3_1.Data, l3_2.Data, l3_3.Data) AS l3Data,
这使得我的查询非常复杂和难以扩展,但目前为止这是我实现的最快结果。
有没有更快、更小的方法来压平这个表格?任何帮助将不胜感激。
提前致谢!