你接近 - 你想要的是UNPIVOT
和PIVOT
組合:
with T AS (
select 1 as element, 1.1 as reading1, 1.2 as reading2, 1.3 as reading3 from dual union all
select 2 as element, 2.1 as reading1, 2.2 as reading2, 2.3 as reading3 from dual union all
select 3 as element, 3.1 as reading1, 3.2 as reading2, 3.3 as reading3 from dual
)
select * from (
select * from t
unpivot (reading_value
for reading_name in ("READING1", "READING2", "READING3")
)
pivot(max(reading_value) for element in (1,2,3)
)
)
order by reading_name
這個查詢
- 將co lumns reading1,reading2,reading3到單獨行(名字進入reading_name,該值成reading_value);這爲我們提供了每(元件,reading_name)一行
- 轉換行 1,2 *,3(的值元件)爲列 '1', '2', '3';這給了我們每reading_name
UPDATE
一行如果元素列表不知道,直到運行時(例如,因爲用戶有選擇他們的選項),你需要一個更動態的方法。下面是一個解決方案,它爲給定的元素列表動態創建一條SQL語句,並使用sys_refcursor
作爲結果集。
-- setup table
create table T AS
select 1 as element, 1.1 as reading1, 1.2 as reading2, 1.3 as reading3 from dual union all
select 2 as element, 2.1 as reading1, 2.2 as reading2, 2.3 as reading3 from dual union all
select 3 as element, 3.1 as reading1, 3.2 as reading2, 3.3 as reading3 from dual ;
/
declare
l_Elements dbms_sql.Number_Table;
function pivot_it(p_Elements in dbms_sql.Number_Table)
return sys_refcursor is
l_SQL CLOB := empty_clob();
l_Result sys_refcursor;
begin
l_SQL := '
select * from (
select * from t
unpivot (reading_value
for reading_name in ("READING1", "READING2", "READING3")
)
pivot(max(reading_value) for element in (';
for i in 1 .. p_Elements.count
loop
l_SQL := l_SQL || to_char(p_Elements(i)) || ',';
end loop;
-- remove trailing ','
l_SQL := regexp_replace(l_SQL, ',$');
l_SQL := l_SQL || ')
)
)';
dbms_output.put_line(l_SQL);
open l_Result for l_SQL;
return l_Result;
end;
begin
l_Elements(1) := 1;
l_Elements(2) := 2;
-- uncomment this line to get all 3 elements
-- l_Elements(3) := 3;
-- return the cursor into a bind variable (to be used in the host environment)
:p_Cursor := pivot_it(l_Elements);
end;
你如何使用這個函數返回的遊標取決於您使用的環境 - 在SQL /加你可以直接打印出來,和大多數編程語言甲骨文綁定支持外的the-框。
CAVEAT:儘管此代碼適用於提供的數據,但它甚至缺少基本的錯誤檢查。這一點尤其重要,因爲動態SQL始終是SQL注入攻擊的可能目標。
嗨,弗蘭克,感謝這工作:),你可以簡要解釋這是如何工作的?提前致謝。 – Kunal 2014-12-02 11:12:08
嗨@Frank,感謝您的更新。查詢返回的元素數量不固定[1,2,3在上面添加]有一個困難。有什麼方法可以在「IN子句」中動態添加值?我嘗試使用LISTAGG(ELEMENTS,','),但是這不起作用。問候,Kunal。 – Kunal 2014-12-02 12:16:39
@Kunal如果元素的數量是可變的,那麼必須使用動態SQL。今天我會試着用一個例子來更新我的答案。 – 2014-12-02 12:21:15