2014-11-01 64 views
0

我有一種情況,我需要將'n'行拆分到列組中。例如,下面是數據集組'n'行到列 - oracle

COMMENT_TEXT 
    T1 
    T2 
    T3 
    T4 
    T5 
    T6 

預期輸出:

SUN MON TUE 
    T1 T2 T3 
    T4 T5 T6 

我的查詢:

SELECT htbp1.comment_text 
FROM hxc_time_building_blocks htbp, 
    hxc_time_building_blocks htbp1 
    WHERE  htbp1.parent_building_block_id = htbp.time_building_block_id 
    AND htbp1.parent_building_block_ovn = htbp.parent_building_block_ovn 
    AND htbp.parent_building_block_id = 116166 
    AND htbp.parent_building_block_ovn = 1  
ORDER BY htbp1.time_building_block_id 

有沒有什麼方法可以讓我做PIVOT用一個 'n' 行無骨料功能?

編輯:T1/T2/T3作爲樣本數據集,但實際上它可以是任意隨機自由文本或null。

SELECT * FROM (SELECT htbp1.comment_text, TO_CHAR (htbp.start_time, 'DY') par_time, 
trunc((rownum-1)/7) buck 
FROM hxc_time_building_blocks htbp, 
hxc_time_building_blocks htbp1, 
hxc_timecard_summary hts 
WHERE  hts.RESOURCE_ID = :p_resource_id 
       AND TRUNC(hts.STOP_TIME) = TRUNC(:p_wkend_date) 
    AND htbp1.parent_building_block_id = htbp.time_building_block_id 
AND htbp1.parent_building_block_ovn = htbp.parent_building_block_ovn 
AND htbp.parent_building_block_id = hts.timecard_id 
AND htbp.parent_building_block_ovn = hts.timecard_ovn  
ORDER BY htbp1.time_building_block_id) PIVOT(max(comment_text) FOR par_time 
                IN ('SUN' AS "SUN", 
                 'MON' AS "MON", 
                 'TUE' AS "TUE", 
                 'WED' AS "WED", 
                 'THU' AS "THU", 
                 'FRI' AS "FRI", 
                 'SAT' AS "SAT")); 

當我添加的另一個表「hxc_timecard_summary」,這是父,然後數據是瘋狂,但如果我在第一使用硬編碼的參數,如一個,則行被顯示出來細。

回答

2

PIVOT還使用了聚合函數,但你並不需要一個GROUP BY:

with tab as (
    select sysdate - 7 date_col, 'T1' comment_text from dual 
    union all select sysdate - 6, 'T2' from dual 
    union all select sysdate - 5, 'T3' from dual 
    union all select sysdate - 4, 'T4' from dual 
    union all select sysdate - 3, 'T5' from dual 
    union all select sysdate - 2, 'T6' from dual 
    union all select sysdate - 1, 'T7' from dual 
) 
select * from (select to_char(date_col, 'D') day_of_week, comment_text from tab) 
PIVOT (max(comment_text) for day_of_week in (7 as sun, 1 as mon, 2 as tue)); 

另外,我想你需要的第二列有一個日期,以形成新的列。

而且您不能使用FOR子句的表達式 - 這應該是列(s)。例如,這是不行的:

select * from tab 
PIVOT (max(comment_text) for to_char(date_col, 'D') in (7 as sun, 1 as mon, 2 as tue)); 

因爲to_char(date_col, 'D')

+0

你真棒。非常感謝。第二個PIVOT的工作,但有一個問題,我跑了。你可以看看編輯過的問題嗎? – Phani 2014-11-01 22:28:02

+0

@Phani,trunc((rownum-1)/ 7)buck - 你不需要這個 – Multisync 2014-11-01 22:34:11

+0

@Phani DY - 這是NLS的依賴,所以要小心 – Multisync 2014-11-01 22:35:27

0

嘗試使用pivot。 它允許將行映射到列。我相信它從11g開始。

+0

這裏的問題是表結構是基於樹的,並且註釋位於樹的第二個節點下。所以,樞軸拋出多行,例如..如果我有7天,如果我的父節點有兩個孩子,那麼它返回14行。 – Phani 2014-11-01 21:48:50

0
with tab as (
    select 'T1' comment_text from dual 
    union all select 'T2' from dual 
    union all select 'T3' from dual 
    union all select 'T4' from dual 
    union all select 'T5' from dual 
    union all select 'T6' from dual 
) 
select regexp_substr(txt, '[^,]+', 1, 1) sun, 
     regexp_substr(txt, '[^,]+', 1, 2) mon, 
     regexp_substr(txt, '[^,]+', 1, 3) tue 
from (
    select buck, wm_concat(comment_text) txt 
    from (
    select comment_text, trunc((rownum-1)/3) buck 
    from (select comment_text from tab order by comment_text) 
)  
    group by buck 
); 

wm_concat(comment_text)(Oracle 10g中)=
listagg(comment_text, ',') within group(order by comment_text)(的Oracle 11g)的

但是這兩個功能都彙總

0

我的第三次嘗試,根本沒有聚合函數(在Oracle 10g中正常工作)

with tab as (
    select 'T1' comment_text from dual 
    union all select 'T2' from dual 
    union all select 'T3' from dual 
    union all select 'T4' from dual 
    union all select 'T5' from dual 
    union all select 'T6' from dual 
) 

select regexp_substr(txt, '[^(#####)]+', 1, 1) sun, 
     regexp_substr(txt, '[^(#####)]+', 1, 2) mon, 
     regexp_substr(txt, '[^(#####)]+', 1, 3) tue 
from (
    select sys_connect_by_path(comment_text, '#####') txt, parent_id 
    from (
    select rownum id, comment_text, mod(rownum-1, 3) parent_id 
    from (select comment_text from tab order by comment_text) 
) 
    start with parent_id = 0 
    connect by prior id = parent_id  
) where parent_id = 2; 
+0

正如我更新我的問題,如果我有任何隨機文本沒有任何模式,它會工作嗎? – Phani 2014-11-01 21:46:03

+0

@Phani sys_connect_by_path(comment_text,',') - 你需要在這裏使用一個不能出現在你的文本中的符號(與regexp_substr相同)​​ – Multisync 2014-11-01 22:16:28

+0

@Phani或一系列符號(我已經更新了我的答案) – Multisync 2014-11-01 22:23:06