- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Oracle实现行列转换的方法分析由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文实例讲述了Oracle实现行列转换的方法。分享给大家供大家参考,具体如下:
1、固定列数的行列转换 。
如:
1
2
3
4
5
6
7
8
9
|
student subject grade
--------- ---------- --------
student1 语文 80
student1 数学 70
student1 英语 60
student2 语文 90
student2 数学 80
student2 英语 100
……
|
转换为:
1
2
3
4
|
语文 数学 英语
student1 80 70 60
student2 90 80 100
……
|
语句如下:
1
2
3
4
5
6
|
select
student,
sum
(decode(subject,
'语文'
, grade,
null
))
"语文"
,
sum
(decode(subject,
'数学'
, grade,
null
))
"数学"
,
sum
(decode(subject,
'英语'
, grade,
null
))
"英语"
from
table
group
by
student;
|
2、不定列行列转换 。
如:
1
2
3
4
5
6
7
8
9
|
c1 c2
--- -----------
1 我
1 是
1 谁
2 知
2 道
3 不
……
|
转换为 。
1
2
3
|
1 我是谁
2 知道
3 不
|
这一类型的转换可以借助于PL/SQL来完成,这里给一个例子 。
1
2
3
4
5
6
7
8
9
10
11
12
|
CREATE
OR
REPLACE
FUNCTION
get_c2(tmp_c1 NUMBER)
RETURN
VARCHAR2
IS
Col_c2 VARCHAR2(4000);
BEGIN
FOR
cur
IN
(
SELECT
c2
FROM
t
WHERE
c1=tmp_c1) LOOP
Col_c2 := Col_c2||cur.c2;
END
LOOP;
Col_c2 := rtrim(Col_c2,1);
RETURN
Col_c2;
END
;
select
distinct
c1 ,get_c2(c1) cc2
from
table
;
|
或者不用pl/sql,利用分析函数和 CONNECT_BY 实现:
1
2
3
4
5
6
7
|
SELECT
c1, SUBSTR (
MAX
(SYS_CONNECT_BY_PATH (c2,
';'
)), 2)
NAME
FROM
(
SELECT
c1, c2, rn, LEAD (rn) OVER (PARTITION
BY
c1
ORDER
BY
rn) rn1
FROM
(
SELECT
c1, c2, ROW_NUMBER () OVER (
ORDER
BY
c2) rn
FROM
t))
START
WITH
rn1
IS
NULL
CONNECT
BY
rn1 =
PRIOR
rn
GROUP
BY
c1;
|
3、列数不固定(交叉表行列转置) 。
这种是比较麻烦的一种,需要借助pl/sql:
原始数据:
1
2
3
4
5
6
7
|
CLASS1 CALLDATE CALLCOUNT
1 2005-08-08 40
1 2005-08-07 6
2 2005-08-08 77
3 2005-08-09 33
3 2005-08-08 9
3 2005-08-07 21
|
转置后:
1
2
3
4
5
|
CALLDATE CallCount1 CallCount2 CallCount3
------------ ---------- ---------- ----------
2005-08-09 0 0 33
2005-08-08 40 77 9
2005-08-07 6 0 21
|
试验如下:
1). 建立测试表和数据 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
CREATE
TABLE
t(
class1 VARCHAR2(2 BYTE),
calldate
DATE
,
callcount
INTEGER
);
INSERT
INTO
t(class1, calldate, callcount)
VALUES
(
'1'
, TO_DATE (
'08/08/2005'
,
'MM/DD/YYYY'
), 40);
INSERT
INTO
t(class1, calldate, callcount)
VALUES
(
'1'
, TO_DATE (
'08/07/2005'
,
'MM/DD/YYYY'
), 6);
INSERT
INTO
t(class1, calldate, callcount)
VALUES
(
'2'
, TO_DATE (
'08/08/2005'
,
'MM/DD/YYYY'
), 77);
INSERT
INTO
t(class1, calldate, callcount)
VALUES
(
'3'
, TO_DATE (
'08/09/2005'
,
'MM/DD/YYYY'
), 33);
INSERT
INTO
t(class1, calldate, callcount)
VALUES
(
'3'
, TO_DATE (
'08/08/2005'
,
'MM/DD/YYYY'
), 9);
INSERT
INTO
t(class1, calldate, callcount)
VALUES
(
'3'
, TO_DATE (
'08/07/2005'
,
'MM/DD/YYYY'
), 21);
COMMIT
;
|
2). 建立ref cursor准备输出结果集 。
1
2
3
4
|
CREATE
OR
REPLACE
PACKAGE pkg_getrecord
IS
TYPE myrctype
IS
REF
CURSOR
;
END
pkg_getrecord;
|
3). 建立动态sql交叉表函数,输出结果集 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
CREATE
OR
REPLACE
FUNCTION
fn_rs
RETURN
pkg_getrecord.myrctype
IS
s VARCHAR2 (4000);
CURSOR
c1
IS
SELECT
',sum(case when Class1='
|| class1
||
' then CallCount else 0 end)'
||
' "CallCount'
|| class1
||
'"'
c2
FROM
t
GROUP
BY
class1;
r1 c1%ROWTYPE;
list_cursor pkg_getrecord.myrctype;
BEGIN
s :=
'select CallDate '
;
OPEN
c1;
LOOP
FETCH
c1
INTO
r1;
EXIT
WHEN
c1%NOTFOUND;
s := s || r1.c2;
END
LOOP;
CLOSE
c1;
s := s ||
' from T group by CallDate order by CallDate desc '
;
OPEN
list_cursor
FOR
s;
RETURN
list_cursor;
END
fn_rs;
|
4). 测试在sql plus下执行:
1
2
3
4
5
6
7
8
|
var results refcursor;
exec
:results := fn_rs;
print results;
CALLDATE CallCount1 CallCount2 CallCount3
--------------- ---------- ---------- ----------
2005-08-09 0 0 33
2005-08-08 40 77 9
2005-08-07 6 0 21
|
说明:decode 。
DECODE(value, if1, then1, if2,then2, if3,then3, . . . else ) 。
Value 代表某个表的任何类型的任意列或一个通过计算所得的任何结果。当每个value值被测试,如果value的值为if1,Decode 函数的结果是then1;如果value等于if2,Decode函数结果是then2;等等。事实上,可以给出多个if/then 配对。如果value结果不等于给出的任何配对时,Decode 结果就返回else .
另外,还可以用decoder函数来比较大小,如下
select decode(sign(变量1-变量2),-1,变量1,变量2) from dual; --取较小值 。
sign()函数根据某个值是0、正数还是负数,分别返回0、1、-1 。
例如:
变量1=10,变量2=20 。
则sign(变量1-变量2)返回-1,decode解码结果为“变量1”,达到了取较小值的目的.
希望本文所述对大家Oracle数据库程序设计有所帮助.
最后此篇关于Oracle实现行列转换的方法分析的文章就讲到这里了,如果你想了解更多关于Oracle实现行列转换的方法分析的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
Oracle 即时客户端和 Oracle 客户端有什么区别?你能给我解释一下吗?谢谢 最佳答案 Oracle 客户端带有安装程序和许多可执行文件,例如 sqlplus,tnsping,它是完整而庞大的
我正在寻找一个Delphi组件来直接连接到ORACLE数据库服务器,而无需安装oracle客户端。 我知道Oracle Data Access (ODAC)来自DevArt 。还有其他组件具有此功能吗
如何编写 Oracle 存储过程,以表 (X) 作为输入参数,并在过程内部使用表 X 来与另一个表 Y 联接? 表 X 将包含数千条记录。 不希望将表名作为 varchar 传递,然后使用动态 SQL
如何编写 Oracle 存储过程,以表 (X) 作为输入参数,并在过程内部使用表 X 来与另一个表 Y 联接? 表 X 将包含数千条记录。 不希望将表名作为 varchar 传递,然后使用动态 SQL
我要过滤COMMENTS属性为空的记录 我试过了 SELECT TABLE_NAME, COMMENTS FROM (SELECT TABLE_NAME, COMMENTS FROM (sel
我要下载 Oracle Instant Client for Linux x86-64 (64-bit)现在有一段时间了。 现在我注意到该网站在过去几个月中一直遇到技术问题。 要从 Oracle 下载
有什么方法可以将我的 Delphi 应用程序 (FireDac) 直接连接到 Oracle 数据库? 目前可以连接,但需要安装Oracle Client 在 embarcadero 站点 ( http
我有一张表,其中日期列的数据格式如下:“7/25/2014 12:14:27 AM”。我需要通过放入 where 子句来获取此日期。有人可以建议我该怎么做吗? 最佳答案 日期(存储在表中)是 repr
如果两个事务试图同时修改同一行会发生什么?通常,一旦行被修改,另一个事务等待直到第一个事务执行提交或回滚。但是,如果他们恰好在同一时刻发送更新请求怎么办? 最佳答案 答案是否定的。两个事务不能同时修改
我想知道为什么我不能在 Oracle 模式中有两个同名的索引?它抛出一个错误,指出该名称已被使用。我的印象是,由于索引在一个特定的表上,这应该不会导致任何错误,除非我们对同一个表上的两个不同列使用相同
我需要构建一个查询来按成员和到期日期检索信息组,但我需要为每个成员提供一个序列号.. 例如: 如果成员“A”有 3 条记录要过期,“B”只有 1 条,“C”有 2 条,我需要这样的结果: Number
独立程序 create procedure proc1 ( begin end; ) 存储过程 create package pkg1 ( procedure proc2 begin end; ) 最
在 Oracle 9i 中声明 FK 时遇到问题。我在这里查看了许多关于 SO 和一些在线文档(例如 http://www.techonthenet.com/oracle/foreign_keys/f
我和我的同事维护的应用程序在后端有一个 Oracle 数据库。我们正在考虑偶尔以“受限”模式运行应用程序,其中一个数据库表空间设置为只读。我们可以轻松地将必要的表和索引移动到单独的表空间,这些表空间将
我想实现一个自定义的回归聚合函数,类似于现有的 REGR_SLOPE . 我要定义的函数需要获取两列作为参数,例如 select T.EMPLOYEE_ID, CUSTOM_REGR_SL
我已经尝试解决这个问题一段时间了,我认为是时候寻求帮助了。我正在构建一个架构配置脚本,我想添加一些脚本输出和错误处理。这个想法是脚本输出窗口只会向我显示关键消息而没有所有噪音。 Create Temp
在旧的 Oracle 服务器(我被告知是 8i)上使用 JDBC 时,我遇到了一个非常令人困惑和奇怪的问题。我在那里准备了一个表,其中包含大约 10 列、数字、varchars、一个 raw(255)
我有一张 table Customer_Chronics在 Oracle 11g 中。 该表具有三个关键列,如下所示: 分支代码 客户 ID 期 我已按 branch_code 列表按表分区,现在我进
是否有存储用户自定义异常的oracle表? 最佳答案 没有。 与其他变量一样,用户定义的异常在 PL/SQL block 中定义,并且具有 PL/SQL 变量将具有的任何范围。所以,例如 DECLAR
在 oracle 中使用序列并使用 Before insert trigger 自动递增列或使用标识列是否更好,因为它在 Oracle 12 c 中可用? 最佳答案 无论哪种方式,您都将使用序列。 1
我是一名优秀的程序员,十分优秀!