我一直在掙扎了一下關於如何處理這種情況的路徑:如何獲得層表
我有一個表結構如下:
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