最近几天一直在弄Oracle-SQL的问题,涉及到了一些平时没有用到的东西,也因此而在这里郁闷了好久。现在问题得到了解决虽说不算完美。但是还是和大家一起分享一下。

行列转换之一:sum(case when.. then.. else.. end) as 语句

这种也可能是我们遇到的第一个行列转换的方法。巧妙的利用汇总和判断语句就可以解决的。

先看一个简单的基础表:如下图

create table STUDENT
(
  STUNAME      NVARCHAR2(50),
  SUBJECTNAME  NVARCHAR2(50),
  SUBJECTSCORE NUMBER
)

表中有两个人的成绩,每一行代表每个学生该学科的成绩。这个也是我们初学SQL时候很常见的一个表结构了。

要求:把上面的多行值以学生为单位转化为2行值,可以很直观的看出每个学生的各科成绩。于是乎便有了下面的语句。

select  
s.stuname,
sum(case when s.subjectname='语文' then  s.subjectscore else 0 end  )  as 语文成绩,
sum(case when s.subjectname='数学' then  s.subjectscore else 0 end  )  as 数学成绩,
sum(case when s.subjectname='英语' then  s.subjectscore else 0 end  )  as 英语成绩
from student s
group by s.stuname
order by s.stuname

执行后所得结果:

上面的做法也很容易让人理解,在这里就不多说了,但是上面的也是有局限性的。因为此处毕竟存在着一些固定值。比如case  中的“语文,数学。。”不过遇到小的业务需求,还是可以拿来直接用的。比如一个学生成绩管理系统这个就可以满足了。

行列转换之二:sys_connect_by_path系统函数,自定义函数,connect by sname = prior sname and rank-1 = prior rank递归 语句

素材还是上面的表,下面我想得到的结果是:

把一个对象的各个学科的属性连接起来放入到一个列中,用字符串存放。

当时看到这个业务需求的时候,当然学生这个只是举个例子。很没有头绪。但是业务那边也急着要数据,没办法。只好硬着头皮想办法。首先就想起了这个要用连接字符串的函数,还需要判断循环之类的。于是乎就想起了这样做,创建一个自定义函数。来处理字符串不断的相加。

方法1:自定义函数,循环

CREATE OR REPLACE FUNCTION getallsubject(parameter varchar2)--有参数方法,字符串
RETURN varchar2
IS
return_str varchar2(4000);--该方法返回一个字符串。
BEGIN
FOR rs IN 
(
SELECT  s.subjectname||':'||s.subjectscore as allshow 
FROM student s
WHERE s.stuname=parameter--当参数一直符合条件 for循环插入结果集rs
) LOOP
return_str:=return_str||rs.allshow;--loop所有字符串,相加
END LOOP;
RETURN return_str;
END;

执行select s.stuname,getallsubject(s.stuname) from  student s

可见,改方法对每一行值都进行了判断,产生了多条记录。然后select distinct s.stuname,getallsubject(s.stuname) from  student s

效果:

得到了想要的结果。

方法2:利用oracle自带的sys_connect_by_path

要说明的是:

所以在使用这个函数之前,我们必须先对源数据进行处理。第一步简单的处理一下。

create table stu1 as

select s.stuname sname,s.subjectname||s.subjectscore  sshow from student s

--
select *from stu1

如下所示:

OK下面就可以写语句了。

select sname as 姓名,allstr 详细描述 from 
(
  select sname,allstr,
  row_number() over(partition by sname order by sname,curr_level desc) ename_path_rank
  from (
         select sname,sshow,rank,level as curr_level,
         ltrim(sys_connect_by_path(sshow,','),',') allstr from --把所有字符串相加
         (
           select s1.sname,s1.sshow,row_number() over(partition by s1.sname order by s1.sname,s1.sshow) rank
           from stu1 s1 order by s1.sname,s1.sshow--创建树关系,name可以作为parentid,rank可以作为childid
         ) connect by sname = prior sname and rank-1 = prior rank
       )
)
where ename_path_rank=1;

执行结果:

也得到了我们想要的结果。当然不用学科之间的间隔符我们可以用replace函数自定义。

比较复杂一点的行列转换用以上两个方法都可以实现。但是这两个方法却都存在着一些优点和缺点。但是本人建议还是使用下面的方法比较靠谱。

虽然结合上面的各种方法解决了这个问题,但是Oracle中字符类型值不能大于4000字节这个问题还一直没解决。我在想有没有一种数据类型,我可以往里面想放多少字节就可以放多少字节的呢。。欢迎各位高手指导!希望可以帮得上遇到该问题的或者是即将遇到该问题的朋友们。

Oracle行列转换的思考与总结的更多相关文章

  1. oracle 行列转换

    oracle 行列转换列名如果是数字,用双引号包住  如下: --  建表 create table workinfo(wid integer primary key,sid integer ,CON ...

  2. oracle行列转换函数的使用

    oracle 10g wmsys.wm_concat行列转换函数的使用: 首先让我们来看看这个神奇的函数wm_concat(列名),该函数可以把列值以","号分隔起来,并显示成一行 ...

  3. Oracle行列转换

    一.建表与插入数据 1.1.建表 create table kecheng ( id NUMBER, name ), course ), score NUMBER ); insert into kec ...

  4. oracle行列转换总结-转载自ITPUB

    原贴地址:http://www.itpub.net/thread-1017026-1-1.html 谢谢原贴大人 最近论坛很多人提的问题都与行列转换有关系,所以我对行列转换的相关知识做了一个总结, 希 ...

  5. Oracle 行列转换总结

    行列转换包括以下六种情况:*列转行*行转列*多列转换成字符串*多行转换成字符串*字符串转换成多列*字符串转换成多行 下面分别进行举例介绍. 首先声明一点,有些例子需要如下10g及以后才有的知识:a.掌 ...

  6. oracle 行列转换函数之WM_CONCAT和LISTAGG的使用(一)

    一.wm_concat函数 wm_concat能够实现同样的功能,但是有时在11g中使用需要用to_char()进行转换,否则会出现不兼容现象(WMSYS.WM_CONCAT: 依赖WMSYS 用户, ...

  7. [Oracle]行列转换(行合并与拆分)

    使用wmsys.wm_concat 实现行合并 在 Oracle  中, 将某一个栏位的多行数据转换成使用逗号风格的一行显示.能够使用函数  wmsys.wm_concat 达成. 这个在上一篇 or ...

  8. oracle 行列转换的运用

    问题: 员工表: A(E_ID,NAME,) 部门表:  B(D_ID,D_NAME) 员工与部门关系:C(ID,E_ID,D_ID) SELECT  A.E_ID,A.NAME ,B.D_NAME ...

  9. Oracle行列转换case when then方法案例

    select (select name from t_area where id=areaid) 区域, end) 一月, end) 二月, end) 三月, end) 四月, end) 五月, en ...

随机推荐

  1. no link present

    今天装linux 系统.然后:service network restart的时候提演示样例如以下的错误: .............................................. ...

  2. 【RapidIO相关】DSP与FPGA通信

    TI参考链接: http://www.ti.com.cn/general/cn/docs/gencontent.tsp?contentId=50741 ------------------------ ...

  3. Ajax的XMLHttpRequest对象的属性和方法总结

    1.redayState属性: 当一个XMLHttpRequest对象被创建后,readyState属性别哦是当前对象正处于什么状态:0:未初始化状态:已经建立:1:准备发送状态:此时XMLHttpR ...

  4. CentOS 7 开放防火墙端口 命令

    iptables防火墙 1.基本操作 # 查看防火墙状态 service iptables status   # 停止防火墙 service iptables stop   # 启动防火墙 servi ...

  5. MySQL的使用笔记

    @Reference Manual (以下简称REF-M) 在官网,选择MySQL Server,选择Documentation,就可以下载了,建议下载PDF 注意版本要对应 很重要,需要的时候就go ...

  6. LeetCode: Permutations 解题报告

    Permutations Given a collection of numbers, return all possible permutations. For example,[1,2,3] ha ...

  7. python 集合比较(交集、并集,差集)集合方法大全

    python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)和 ...

  8. Zabbix添加自定义监控项(一)

    前言:由于Zabbix提供的项目和模板有限,有时我们需要自定义监控项,下面以监控磁盘I/O使用率为例,创建自动发现规则,并配置图形. (1)Zabbix_agentd端自动发现脚本,zabbix要求返 ...

  9. wp中的动画

    动画目标:必须是依赖属性.可以用于Double,Color,Point,Object类型.对应的动画类后面加Animation,下面代码演示旋转360°. <Button Content=&qu ...

  10. 【转】【Unity】DateTime各种时间字符串

    各种表示时间的方法 谢谢网络上的大神 此片为转载的文章 DateTime.Now.ToShortTimeString() DateTime dt = DateTime.Now; dt.ToString ...