在Oracle SQL的单列中转换两个列的值

时间:2018-11-08 14:02:18

标签: sql database oracle

我下面有这样的桌子

SNO     Name    Sales   Profit
1      John       50    20
2      Peter      60    0 
3      Mark       15    10
4      Nicolas      0  -10
5      Alex       70    20

我想将其转换为以下内容(即,销售和利润值应合并为一列)。

SNO     Name     Sales_Profit Values
1      John        Sales      50
1      John        profit     20
2      Peter       Sales      60
2      Peter       Profit      0

,依此类推。

没有功能/程序,是否有任何方法可以处理这种情况?

2 个答案:

答案 0 :(得分:4)

一种方法使用cross join

select t.sno, s.name, sp.salesprofit,
       (case when sp.salesprofit = 'Sales' then sales else profit end) as values
from t cross join
     (select 'Profit' as salesprofit from dual union all
      select 'Sales' from dual
     ) sp;

union all相比,此方法的优势在于它只应扫描一次表。

答案 1 :(得分:2)

Oracle在版本11.1中引入了unpivot运算符,正是针对这种问题。如下图所示。我在with子句中创建了示例数据(不是查询的一部分,不能回答您的问题;您应该删除它,并使用实际的表名)。请注意,values是oracle保留字,因此不应用作列名。我改用value。列名中不应包含正斜杠;我用下划线代替了。

with
  base_data (sno, name, sales, profit) as (
    select 1, 'John'   , 50,  20 from dual union all
    select 2, 'Peter'  , 60,   0 from dual union all 
    select 3, 'Mark'   , 15,  10 from dual union all
    select 4, 'Nicolas',  0, -10 from dual union all
    select 5, 'Alex'   , 70,  20 from dual
  )
select  *
from    base_data
unpivot include nulls 
    (value for sales_profit in (sales as 'Sales', profit as 'Profit'))
;

 SNO NAME    SALES_PROFIT  VALUE
---- ------- ------------ ------
   1 John    Sales            50
   1 John    Profit           20
   2 Peter   Sales            60
   2 Peter   Profit            0
   3 Mark    Sales            15
   3 Mark    Profit           10
   4 Nicolas Sales             0
   4 Nicolas Profit          -10
   5 Alex    Sales            70
   5 Alex    Profit           20