2016-12-06 51 views
1

我想生成一個數據層次結構。使用SYS_CONNECT_BY_PATH來合計值

這個查詢:

select connect_by_root(parent_id) as root_id 
     ,ID, NAME 
     ,SYS_CONNECT_BY_PATH(PARENT_ID,'/') PATH 
     ,level 
     ,line 
     ,LINE*power(10,-level+1) CALC 
     ,ltrim(SYS_CONNECT_BY_PATH(lpad(LINE,3,'0'), '.'),'.') SORT 
from (

    select 3 ID, 1 LINE, 2 PARENT_ID FROM DUAL 
    union all 
    select 4 ID, 2 LINE, 2 PARENT_ID FROM DUAL 
    union all 
    select 5 ID, 3 LINE, 2 PARENT_ID FROM DUAL 
    union all 
    select 6 ID, 1 LINE, 5 PARENT_ID FROM DUAL 
    union all 
    select 7 ID, 1 LINE, 6 PARENT_ID FROM DUAL 

) v 
start with v.parent_id = 2 
connect by nocycle prior id=parent_id 

生成:

ROOT_ID ID PATH  LEVEL LINE CALC SORT 
2  3 /2  1  1  1  001 
2  4 /2  1  2  2  002 
2  5 /2  1  3  3  003 
2  6 /2/5 2  1  0.1  003.001 
2  7 /2/5/6 3  1  0.01 003.001.001 

我想什麼:

ROOT_ID ID PATH  LEVEL LINE CALC  
2  3 /2  1  1  1  
2  4 /2  1  2  2  
2  5 /2  1  3  3  
2  6 /2/5 2  1  3.1  
2  7 /2/5/6 3  1  3.11 

有沒有辦法讓sys_connect_by_path(或其他功能)相符的CALC列及其父母?

目前,我使用SORT字段來排序行;我寧願排序一個合適的數值(CALC字段)。

回答

1

試試這個:

select connect_by_root(parent_id) as root_id 
     ,ID 
     ,SYS_CONNECT_BY_PATH(PARENT_ID,'/') PATH 
     ,level 
     ,line 
     ,LINE*power(10,-level+1) CALC 
     ,XMLCAST(XMLQUERY(ltrim(SYS_CONNECT_BY_PATH(LINE*power(10,-level+1), '+'),'+') RETURNING CONTENT) AS NUMBER) SORT 
from (

    select 3 ID, 1 LINE, 2 PARENT_ID FROM DUAL 
    union all 
    select 4 ID, 2 LINE, 2 PARENT_ID FROM DUAL 
    union all 
    select 5 ID, 3 LINE, 2 PARENT_ID FROM DUAL 
    union all 
    select 6 ID, 1 LINE, 5 PARENT_ID FROM DUAL 
    union all 
    select 7 ID, 1 LINE, 6 PARENT_ID FROM DUAL 

) v 
start with v.parent_id = 2 
connect by nocycle prior id=parent_id 
+0

不錯!我在想,一個'eval'函數會有所幫助。 – craig

1

你可以把你的SORT列與一些fidling後(改變第一點,以逗號和刪除其他點)的結果轉換爲數字。

的關鍵部分是在這裏

to_number(regexp_replace(regexp_replace(SORT,'\.',',',1,1),'\.',null), 
    '99D9999' , ' NLS_NUMERIC_CHARACTERS = '',.'' ') sort2 

3.1.1 - >3,1.1 - >3,11並轉換爲數字

這裏完整的查詢

with v as (
    select 3 ID, 1 LINE, 2 PARENT_ID FROM DUAL 
    union all 
    select 4 ID, 2 LINE, 2 PARENT_ID FROM DUAL 
    union all 
    select 5 ID, 3 LINE, 2 PARENT_ID FROM DUAL 
    union all 
    select 6 ID, 1 LINE, 5 PARENT_ID FROM DUAL 
    union all 
    select 7 ID, 1 LINE, 6 PARENT_ID FROM DUAL 

), v2 as (
select connect_by_root(parent_id) as root_id 
     ,ID 
     ,SYS_CONNECT_BY_PATH(PARENT_ID,'/') PATH 
     ,level my_level 
     ,line 
     ,LINE*power(10,-level+1) CALC 
     ,ltrim(SYS_CONNECT_BY_PATH(LINE , '.'),'.') SORT 
from  v 
start with v.parent_id = 2 
connect by nocycle prior id=parent_id 
) 
select ROOT_ID, ID, PATH, my_level, LINE, CALC, SORT, 
to_number(regexp_replace(regexp_replace(SORT,'\.',',',1,1),'\.',null),'99D9999' , ' NLS_NUMERIC_CHARACTERS = '',.'' ') sort2 
from v2