sql - Transpose Query Result in Oracle 11g -
i have query returns out result in following form:
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 ---------------------------------------
i want output in following form:
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
i.e have transpose table. have tried using oracle pivot following way:
with t ( select  element,reading1 zzz;    ----(1) ) select * t pivot( max(reading1) element in (1,2,3,..n))     ----(2)   this gives me result reading1,however unable produce result readings correctly. highly appreciated.
thanks in advance,
best regards, kunal
you're close - want combination of unpivot , pivot:
with t (   select 1 element, 1.1 reading1, 1.2 reading2, 1.3 reading3 dual union   select 2 element, 2.1 reading1, 2.2 reading2, 2.3 reading3 dual union   select 3 element, 3.1 reading1, 3.2 reading2, 3.3 reading3 dual  ) select * (   select * t   unpivot (reading_value     reading_name in ("reading1", "reading2", "reading3")     )   pivot(max(reading_value) element in (1,2,3)   ) ) order reading_name   this query
- converts columns reading1, reading2, reading3 separate rows (the name goes reading_name, value reading_value); gives 1 row per (element,reading_name)
 - converts rows 1, 2*, 3 (the values element) columns '1', '2', '3'; gives 1 row per reading_name
 
update
if list of elements not know until run time (e.g. because user has option of selecting them), need more dynamic approach. here's 1 solution dynamically creates sql statement given list of elements , uses sys_refcursor result set.
-- setup table create table t    select 1 element, 1.1 reading1, 1.2 reading2, 1.3 reading3 dual union   select 2 element, 2.1 reading1, 2.2 reading2, 2.3 reading3 dual union   select 3 element, 3.1 reading1, 3.2 reading2, 3.3 reading3 dual ;   /  declare   l_elements dbms_sql.number_table;    function pivot_it(p_elements in dbms_sql.number_table)      return sys_refcursor       l_sql clob := empty_clob();       l_result sys_refcursor;     begin       l_sql := '         select * (           select * t              unpivot (reading_value               reading_name in ("reading1", "reading2", "reading3")             )           pivot(max(reading_value) element in (';       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 l_sql;       return l_result;   end;       begin   l_elements(1) := 1;   l_elements(2) := 2;   -- uncomment line 3 elements   -- l_elements(3) := 3;   -- return cursor bind variable (to used in host environment)   :p_cursor := pivot_it(l_elements);   end;   how use cursor returned function depends on environment you're using - in sql/plus can print it, , programming languages' oracle bindings support out-of-the-box.
caveat: while code works data provided, lacks basic error checking. important because dynamic sql possible target sql injection attacks.
Comments
Post a Comment