2016-05-17 4 views
0

У меня есть это:Транспонирование несколько столбцов же

Year Apple Orange 
1  100  150 
2  200  250 
3  300  350 
2  200  250 
1  100  150 

мне это нужно:

Fruit  1   2   3 
Apple  200   400   300 
Orange  300   500   350 

У меня есть вариант А и вариант Б, но он не переставляет только 1 плод, если я сделайте «Союз всех».

Вариант А:

select 
    'Apple' as Fruit 
    ,MAX(DECODE(year, '1', sum(Apple)) "1" 
    ,MAX(DECODE(year, '2', sum(Apple)) "2" 
from MyTable 

Вариант B:

select 
    * 
from (
    select 
      Apple 
      ,Year 
    from MyTable 
    ) 
PIVOT(sum(Apple) for year in ('1', '2', '3')) 

Вопрос:

Can U транспонировать все столбцы без "Союза"?

ответ

4

Oracle Setup:

CREATE TABLE table_name (year, apple, orange) AS 
SELECT 1, 100, 150 FROM DUAL UNION ALL 
SELECT 2, 200, 250 FROM DUAL UNION ALL 
SELECT 3, 300, 350 FROM DUAL UNION ALL 
SELECT 2, 200, 250 FROM DUAL UNION ALL 
SELECT 1, 100, 150 FROM DUAL; 

Запрос - UNPIVOT затем стержень:

SELECT * 
FROM (
    SELECT * 
    FROM table_name 
    UNPIVOT(value FOR fruit IN (Apple, Orange)) 
) 
PIVOT (SUM(value) FOR year IN (1, 2, 3)); 

Выход:

FRUIT 1 2 3 
------ --- --- --- 
ORANGE 300 500 350 
APPLE 200 400 300 
+0

Я собирался ответить с другим подходом, но это должно быть именно то, что ОП хочет. +1 – ruudvan

1

Это как ча n делать это динамически.

Создание заявления

CREATE TABLE MyTable 
    (Year int, Apple int, Orange int) ; 
INSERT ALL 
    INTO MyTable (Year, Apple, Orange)  VALUES (1, 100, 150) 
    INTO MyTable (Year, Apple, Orange)  VALUES (2, 200, 250) 
    INTO MyTable (Year, Apple, Orange)  VALUES (3, 300, 350) 
    INTO MyTable (Year, Apple, Orange)  VALUES (2, 200, 250) 
    INTO MyTable (Year, Apple, Orange)  VALUES (1, 100, 150) 
SELECT * FROM dual; 

Выполнить это в SQL Developer или SQLPlus (я пробовал в SQL Developer). Или вы можете инкапсулировать его в процедуру и можете вернуть результат.

SET ServerOutput ON size 100000; 
variable rc refcursor; 
DECLARE 
v_column_list varchar2 (2000); 
v_years varchar2(2000); 
BEGIN 
    SELECT listagg('"' || column_name || '"', ',') within 
    GROUP (ORDER BY column_id) 
    INTO v_column_list 
    FROM all_tab_columns 
    WHERE table_name = 'MYTABLE' 
     AND column_name <> 'YEAR'; 

    SELECT listagg(year, ',') within 
    GROUP (ORDER BY year) 
    INTO v_years 
    FROM (
     SELECT DISTINCT year 
     FROM MyTable); 
-- dbms_output.put_line(' v_column_list =' || v_column_list); 
-- dbms_output.put_line(' v_years =' || v_years); 
    OPEN :rc FOR 
    'SELECT * FROM 
    (SELECT * 
     FROM MyTable 
      UNPIVOT (val for fruit in (' || v_column_list || ') 
       ) 
    ) 
    PIVOT (sum (val) for year in (' || v_years || '))'; 
END; 
/

PRINT :rc 

Выход:

------------------------------------------------------------------------ 
FRUIT 1      2      3      
------ ---------------------- ---------------------- ---------------------- 
ORANGE 300      500      350     
APPLE 200      400      300