Sql Oracle将多个列合并为一个列
我有一个关于Oracle Sql的问题 如果我有一个名为a的数据,有8列:Sql Oracle将多个列合并为一个列,sql,oracle,row,transform,Sql,Oracle,Row,Transform,我有一个关于Oracle Sql的问题 如果我有一个名为a的数据,有8列: Spot| ID |Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday ------------------------------------------------------------------------- A| 1 | 0.1 |0.15 | ........................................... -
Spot| ID |Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday
-------------------------------------------------------------------------
A| 1 | 0.1 |0.15 | ...........................................
-------------------------------------------------------------------------
A| 2 | 0.2 |0.2 | ...........................................
-------------------------------------------------------------------------
A| 3 | 0.3 |0.25 | ...........................................
-------------------------------------------------------------------------
A| 4 | 0.4 |0.4 | ...........................................
-------------------------------------------------------------------------
我可以将其转换为如下表B:
Spot| Day of Week | ID | Value
-------------------------------------------------------------------------
A| 1 | 1 | 0.1
-------------------------------------------------------------------------
A| 1 | 2 | 0.2
-------------------------------------------------------------------------
A| 1 | 3 | 0.3
-------------------------------------------------------------------------
A| 1 | 4 | 0.4
-------------------------------------------------------------------------
A| 2 | 1 | 0.15
-------------------------------------------------------------------------
.......................................................................
select spot, 1 as day_of_week, id, sunday as value from a union all
select spot, 2 , id, monday from a union all
.......
select spot, day_of_week, id, value
from a
unpivot ( value for day_of_week in ( sunday as 1, monday as 2, .... ) )
;
将周日至周六的专栏合并为一个新的专栏,名为“周中的一天”
请问我怎么做?谢谢 基本上有三种方法可以做到这一点,每种方法各有优缺点。可能不止三个,这些是我知道的 第一种方法使用UNIONALL,对于小表来说很好,性能并不重要。它适用于Oracle的任何版本。事情是这样的:
Spot| Day of Week | ID | Value
-------------------------------------------------------------------------
A| 1 | 1 | 0.1
-------------------------------------------------------------------------
A| 1 | 2 | 0.2
-------------------------------------------------------------------------
A| 1 | 3 | 0.3
-------------------------------------------------------------------------
A| 1 | 4 | 0.4
-------------------------------------------------------------------------
A| 2 | 1 | 0.15
-------------------------------------------------------------------------
.......................................................................
select spot, 1 as day_of_week, id, sunday as value from a union all
select spot, 2 , id, monday from a union all
.......
select spot, day_of_week, id, value
from a
unpivot ( value for day_of_week in ( sunday as 1, monday as 2, .... ) )
;
这是低效的,因为基表A被读取七次,每个UNIONALL分支读取一次。有些行可能会被缓存,所以可能不是I/O时间乘以7,但效率仍然很低
自Oracle 11.1以来,我们有了PIVOT和UNPIVOT。您需要取消激励,如下所示:
Spot| Day of Week | ID | Value
-------------------------------------------------------------------------
A| 1 | 1 | 0.1
-------------------------------------------------------------------------
A| 1 | 2 | 0.2
-------------------------------------------------------------------------
A| 1 | 3 | 0.3
-------------------------------------------------------------------------
A| 1 | 4 | 0.4
-------------------------------------------------------------------------
A| 2 | 1 | 0.15
-------------------------------------------------------------------------
.......................................................................
select spot, 1 as day_of_week, id, sunday as value from a union all
select spot, 2 , id, monday from a union all
.......
select spot, day_of_week, id, value
from a
unpivot ( value for day_of_week in ( sunday as 1, monday as 2, .... ) )
;
这将更快地工作;目前还不清楚Oracle是如何在幕后实现这一点的,它可能仍然会实现一个联合,但它是一个智能的联合——同一行被使用七次,而不是从磁盘重复读取。当然,缺点是它在较旧版本的Oracle中不可用
第三种方法使用笛卡尔连接。它的工作速度很快,并且可以在所有版本中使用
select a.spot, h.day_of_week, id,
case h.day_of_week when 1 then sunday
when 2 then monday
..................
when 7 then saturday
end as value
from a
cross join
( select level as day_of_week from dual connect by level <= 7) h
;
这个解决方案中的子查询h看起来很奇特,但它所做的只是创建一个内联视图h,其中包含一列,day_of_week,值从1到7。它可以以任何其他方式创建,这只是一种快速而常见的方式。您可以使用UNPIVOT:
Oracle安装程序:
查询:
输出:
我相信UNPIVOT会帮助你:听起来很棒@JacobH我会看看