我有一个查询,它返回以下表格中的结果:
Element READING1 READING2 READING3 --------------------------------------- 1 0.25 1.5 3.5 2 1.3 2.3 5.5 3 4.5 5.5 4.3 .. .. .. .. n 1.5 2.3 5.5 ---------------------------------------
我希望以下列形式输出:
1 2 3 .. n --------------------------------------- READING1 0.25 1.3 4.5 .. 1.5 READING2 1.5 2.3 5.5 .. 2.3 READING3 3.5 5.5 4.3 .. 5.5
,我必须转移表格。 我尝试过以下方式使用Oracle Pivot:
WITH T AS (
SELECT Element,READING1 from ZZZ; ----(1)
)
SELECT * FROM T
PIVOT( MAX(READING1) FOR ELEMENT IN (1,2,3,..n)) ----(2)
这只给了READING1的结果,但是我无法正确地产生所有读数的结果。任何帮助都将受到高度赞赏。
先谢谢,
最诚挚的问候, KUNAL
答案 0 :(得分:2)
您已关闭 - 您想要的是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
此查询
<强>更新强>
如果在运行时之前不知道元素列表(例如,因为用户可以选择它们),则需要更动态的方法。这是一个解决方案,它为给定的元素列表动态创建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 / Plus中,您只需打印它,以及大多数编程语言&#39; Oracle绑定支持它开箱即用。
CAVEAT:虽然此代码适用于所提供的数据,但它甚至缺少基本的错误检查。这一点尤为重要,因为动态SQL始终是SQL注入攻击的可能目标。