2014-04-01 35 views
1

可以說我有一個表作爲以下結構:查詢XMLType列

創建表溫度(ID數字,數據的XMLType);

和ID 1內容

<PivotSet> 
<item> 
    <column name = "ATTRIBUTENAME">test</column> 
    <column name = "MAX(ATTRIBUTEVALUE)">testVal</column> 
</item> 
<item> 
    <column name = "ATTRIBUTENAME">test1</column> 
    <column name = "MAX(ATTRIBUTEVALUE)">test1Val</column> 
</item> 
<item> 
    <column name = "ATTRIBUTENAME">test2</column> 
    <column name = "MAX(ATTRIBUTEVALUE)">test2Val</column> 
</item> 

現在我一直渴望實現的是扁平化在XML中的元素,得到這個結果:

id | test | test 1 | test 2 | 
    1 |testval |testval1 |testval2 | 

所以我想要的是每個項目顯示有第一個<column>columnName,第二個作爲該列的值。

回答

1
SQL> select * from t; 

     ID                  
----------                  
DATA                    
-------------------------------------------------------------------------------- 
     1                  
<PivotSet>                  
    <item>                   
    <column name="ATTRIBUTENAME">test</column>         
    <column name="MAX(ATTRIBUTEVALUE)">testVal</column>       
    </item>                  
    <item>                   
    <column name="ATTRIBUTENAME">test1</column>         
    <column name="MAX(ATTRIBUTEVALUE)">test1Val</column>       
    </item>                  
    <item>                   
    <column name="ATTRIBUTENAME">test2</column>         
    <column name="MAX(ATTRIBUTEVALUE)">test2Val</column>       
    </item>                  
</PivotSet>  

SQL> select 'ID' cn, 
    2 max(decode(rn,1,column_name,null)) a, 
    3 max(decode(rn,2,column_name,null)) b, 
    4 max(decode(rn,3,column_name,null)) c, 
    5 id, 
    6 max(decode(rn,1,value,null)) d, 
    7 max(decode(rn,2,value,null)) e, 
    8 max(decode(rn,3,value,null)) f 
    9 from (
10 select id, extractValue(value(r),'item/column[@name = "ATTRIBUTENAME"]') column_name 
11 , extractValue(value(r),'item/column[@name = "MAX(ATTRIBUTEVALUE)"]') value 
12 , row_number() over(partition by id order by null) rn 
13 from t, 
14 table(XMLSequence((t.data).extract('PivotSet/item'))) r 
15 ) group by id 
16/

CN A  B  C   ID D  E  F       
-- -------- -------- -------- ---- -------- -------- --------     
ID test  test1 test2  1 testVal test1Val test2Val 

或(對於這個問題的新版本)

SQL> select id, a, b, c 
    2 from (
    3 select 'ID' id, max(decode(rn, 1, column_name)) a, max(decode(rn, 2, column_name)) b, max(decode(rn, 3, column_name)) c, 1 s 
    4 from (
    5 select id, extractValue(value(r),'item/column[@name = "ATTRIBUTENAME"]') column_name 
    6 , extractValue(value(r),'item/column[@name = "MAX(ATTRIBUTEVALUE)"]') value 
    7 , row_number() over(partition by id order by null) rn 
    8 from t, 
    9 table(XMLSequence((t.data).extract('PivotSet/item'))) r 
10 ) 
11 group by id 
12 union all 
13 select to_char(id), max(decode(rn, 1, value)), max(decode(rn, 2, value)), max(decode(rn, 3, value)) c, 2 s 
14 from (
15 select id, extractValue(value(r),'item/column[@name = "ATTRIBUTENAME"]') column_name 
16 , extractValue(value(r),'item/column[@name = "MAX(ATTRIBUTEVALUE)"]') value 
17 , row_number() over(partition by id order by null) rn 
18 from t, 
19 table(XMLSequence((t.data).extract('PivotSet/item'))) r 
20 ) 
21 group by id 
22 ) order by id, s 
23/

ID          A  B  C      
---------------------------------------- -------- -------- --------    
ID          test  test1 test2     
1          testVal test1Val test2Val 

(不能使用保條款由於在11.2.3 ORA-00600)

+0

謝謝,越來越接近解。有沒有辦法讓<< item/column [@name =「ATTRIBUTENAME」] >>作爲列名而不是A B C?而另一個我稍後保存的棘手部分是如果我們有一組未知的這個查詢會是什麼樣子? – user3485103

+0

然後看動態SQL。靜態的人需要事先知道最大列數。列名同樣如此。 –

+0

好的隊友感謝主角。我將看看動態sql。 – user3485103