Oracle - 选择要转动的语句并更改数据的显示方式

时间:2016-11-30 21:05:23

标签: oracle pivot union

我目前在Oracle表格中有数据如下所示:

Person_ID   Fieldname              Fieldnumber
123         2016 Salary            50000
123         2015 Salary            45000
123         2014 Salary            40000
123         2016 Vacation Days     5
456         2016 Salary            50000
456         2016 Vacation Days     5
789         2016 Salary            90000
789         2016 Vacation Days     5

我想向Pivot写一个select语句并更改数据的显示,使它看起来像这样:

Person_ID    Fieldname      2016         2015         2014
123          Salary         55000        45000        40000
123          Vacation Days  5  
456          Salary         50000      
456          Vacation Days  5                                  
789          Salary         90000                                        
789          Salary         5

如何执行此操作以便在添加新字段名称时,我的SQL会在运行时自动添加新列?有没有办法用pivot来做这个,还是我应该使用union或其他我不熟悉的函数?

我经常运行的支点看起来像这样,但我不认为这个概念在这种情况下会起作用:

select *
  from cust_matrix
unpivot
(
  state_counts
    for state_code in ("New York","Conn","New Jersey","Florida","Missouri")
)
order by "Puchase Frequency", state_code

谢谢

1 个答案:

答案 0 :(得分:1)

不要因为有两列不属于" pivot",在您的案例person_idfieldname中而感到困惑。透视的工作原理完全相同。

注意 - 您的输入表显然缺少列名(对于年份) - 最好不要是Year,Oracle中的保留字。我在我的示例输入中使用了yr。你输出中也有一个拼写错误(2016年的55000来自哪里,person_id = 123?输入有50000)。

并且,您可以将2016作为列名,但它必须是双引号,以后可能会导致意外问题。最好使用标准列名称 - 特别是不能以数字开头。我使用了y2016等。

with 
     inputs ( person_id, yr, fieldname, fieldnumber ) as (
       select 123, 2016, 'Salary'       , 50000 from dual union all
       select 123, 2015, 'Salary'       , 45000 from dual union all
       select 123, 2014, 'Salary'       , 40000 from dual union all
       select 123, 2016, 'Vacation Days',     5 from dual union all
       select 456, 2016, 'Salary'       , 50000 from dual union all
       select 456, 2016, 'Vacation Days',     5 from dual union all
       select 789, 2016, 'Salary'       , 90000 from dual union all
       select 789, 2016, 'Vacation Days',     5 from dual
     )
-- end of test data; actual solution (SQL query) begins below this line
select person_id, fieldname, y2016, y2015, y2014
from   inputs
pivot ( max(fieldnumber) for yr in (2016 as y2016, 2015 as y2015, 2014 as y2014) )
order by person_id, fieldname
;

PERSON_ID  FIELDNAME      Y2016  Y2015  Y2014
---------  -------------  -----  -----  -----
123        Salary         50000  45000  40000
123        Vacation Days      5     
456        Salary         50000     
456        Vacation Days      5     
789        Salary         90000     
789        Vacation Days      5