我下面有这样的桌子
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
,依此类推。
没有功能/程序,是否有任何方法可以处理这种情况?
答案 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