Sql Oracle将多个列合并为一个列

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 | ........................................... -

我有一个关于Oracle Sql的问题

如果我有一个名为a的数据,有8列:

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我会看看