我一直在挣扎了一下关于如何处理这种情况的路径:如何获得层表
我有一个表结构如下:
Family_code | Parent_Family_Code | ....
1 2
2 4
3 6
4 3
......................
当用户搜索特定家族码,我需要返回的整个路径(最多10个级别最大),所以例如用于family_code = 1,我需要:
Family_code | parent_1 | p_2 | p_3 | p_4 | p_5 | .....
1 2 4 3 6 null null.....
我知道我可以使用sys_connect_by_path()
这将带给我预期的结果,但作为一个字符串,而不是单独的列,这是我宁愿避免的。
这也可以通过10个左连接来完成同一个表,或者使用LEAD()/LAG()
函数,这些函数将包含大量的子查询,并且会造成凌乱和难以理解的查询,但是再一次,这将会更加沉重那么它应该是,我需要尽可能简化它。
我想出了使用substr()
功能的解决方案(代码的长度将永远是VARCHAR2(3)):
SELECT s.family_code,
s.parent_family_code_1,
s.parent_family_code_2,
CASE WHEN length(s.family_path) - (4 * 3 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 3 + 2), 3) ELSE NULL END as parent_family_code_3,
CASE WHEN length(s.family_path) - (4 * 4 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 4 + 2), 3) ELSE NULL END as parent_family_code_4,
CASE WHEN length(s.family_path) - (4 * 5 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 5 + 2), 3) ELSE NULL END as parent_family_code_5,
CASE WHEN length(s.family_path) - (4 * 6 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 6 + 2), 3) ELSE NULL END as parent_family_code_6,
CASE WHEN length(s.family_path) - (4 * 7 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 7 + 2), 3) ELSE NULL END as parent_family_code_7,
CASE WHEN length(s.family_path) - (4 * 8 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 8 + 2), 3) ELSE NULL END as parent_family_code_8,
CASE WHEN length(s.family_path) - (4 * 9 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 9 + 2), 3) ELSE NULL END as parent_family_code_9,
CASE WHEN length(s.family_path) - (4 * 10 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 10 + 2), 3) ELSE NULL END as parent_family_code_10
FROM (SELECT t.family_code,
t.parent_family_code as parent_family_code_1,
prior t.parent_family_code as parent_family_code_2,
sys_connect_by_path(t.family_code, ',') as family_path
FROM table t
connect by prior t.family_code = t.parent_family_code) s
但我想没有,因为它使用的子串的解决方案当其他开发人员碰到它时,将很难做任何修改。 。 所以基本上我的问题是 - 如何在不使用子串的情况下选择整个路径作为不同的列?
已编辑成问题的代码不工作 - 如果你也可以'SELECT family_path'然后你会看到(a)它没有得到整个路径,(b)由于你有可变长度的字符串并且使用了固定长度的条件,所以这个路径并不是全部被子字符串处理。 – MT0
如果你想要整个路径,那么你可以使用'sys_connect_by_path(t.parent_family_code,',')|| ','|| t.family_code作为family_path',但它仍然不能解决案例条件中可变长度数据和固定长度的第二个问题。 – MT0