我对Oracle Sql有疑问,
如果我有一个名为A的数据,有8列:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main_topbar">Main Topbar</div>
<div id="main_content">
<div id="content">
Bla sdlkkgj sa;lkfjj a;lkgj a;lkgj ja;lkg jal;kg jdlgkjd lgkjdf lgjhdfjhdgfb mfnbvufhfkkhkjhgjh ggjhg <br>bla<br>bladiebla<br>Bla<br>bla<br>bladiebla<br>Bla<br>bla<br>bladiebla<br>Bla<br>bla<br>bladiebla<br>Bla<br>bla<br>bladiebla<br>Bla<br>bla<br>bladiebla<br>Bla<br>bla<br>bladiebla<br>Bla<br>bla<br>bladiebla<br>Bla<br>bla<br>bladiebla
</div>
</div>
我可以将它转换为表格B:
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 | ...........................................
-------------------------------------------------------------------------
将列(星期日到星期六)组合到名为“星期几”的新列
我该怎么办呢?谢谢!
答案 0 :(得分:1)
基本上有三种方法可以做到这一点,每种方法各有优缺点。 (可能有三个以上,这些是我所知道的。)
第一种方法使用UNION ALL
,它适用于小型表(性能并不重要)。它适用于任何版本的Oracle。它是这样的:
select spot, 1 as day_of_week, id, sunday as value from a union all
select spot, 2 , id, monday from a union all
.......
这是低效的,因为基表(A)被读取七次,UNION ALL
的每个分支被读取一次。有些行可能会被缓存,所以也许它不是完全I / O时间乘以7,但它仍然效率低下。
自Oracle 11.1起,我们已经有PIVOT
和UNPIVOT
。你需要透视,像这样:
select spot, day_of_week, id, value
from a
unpivot ( value for day_of_week in ( sunday as 1, monday as 2, .... ) )
;
这会更快;目前尚不清楚Oracle是如何实现这一目标的,它可能仍然会执行UNION ALL
,但它是一个智能的 - 其中同一行使用了七次,而不是从磁盘重复读取。当然,缺点是它在旧版本的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它可以用任何其他方式创建,这只是一个快速(和常见)的方式。
答案 1 :(得分:1)
您可以使用UNPIVOT
:
Oracle安装程序:
CREATE TABLE your_table ( spot, id, sunday, monday, tuesday, wednesday, thursday, friday, saturday ) AS
SELECT 'A', 1, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4 FROM DUAL UNION ALL
SELECT 'A', 2, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45 FROM DUAL UNION ALL
SELECT 'A', 3, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5 FROM DUAL;
<强>查询强>:
SELECT *
FROM your_table
UNPIVOT ( Value FOR Day_of_week IN (
sunday AS 1,
monday AS 2,
tuesday AS 3,
wednesday AS 4,
thursday AS 5,
friday AS 6,
saturday AS 7
) );
<强>输出强>:
S ID DAY_OF_WEEK VALUE
- -- ----------- -----
A 1 1 .1
A 1 2 .15
A 1 3 .2
A 1 4 .25
A 1 5 .3
A 1 6 .35
A 1 7 .4
A 2 1 .15
A 2 2 .2
A 2 3 .25
A 2 4 .3
A 2 5 .35
A 2 6 .4
A 2 7 .45
A 3 1 .2
A 3 2 .25
A 3 3 .3
A 3 4 .35
A 3 5 .4
A 3 6 .45
A 3 7 .5