行转列的通用过程

小灰狼W 2009-10-19 11:39:52
经常遇到发帖求行列转换的代码,用max(decode(..))回复后,十有八九会再问一句:如果列名不固定,或者列数不固定怎么办。就要用存储过程来写,这些存储过程的代码都大同小异,我就想能不能写个通用点的过程
试了一下,把结果发出来
create or replace procedure proc(tabname in varchar2,
col1 in varchar2,
col2 in varchar2,
col3 in varchar2,
viewname in varchar2 default 'v_tmp')
as
sqlstr varchar2(2000):='create or replace view '||viewname||' as select '||col1||' ';
c1 sys_refcursor;
v1 varchar2(100);
begin
open c1 for 'select distinct to_char('||col2||') from '||tabname;
loop
fetch c1 into v1;
exit when c1%notfound;
sqlstr:=sqlstr||'
,max(decode('||col2||','''||v1||''','||col3||'))"'||v1||'"';
end loop;
close c1;
sqlstr:=sqlstr||' from '||tabname||' group by '||col1;
execute immediate sqlstr;
end proc;

这里的几个参数,tabname指的是需要进行行列转换的表名,col1是这个表中行列转换以后要根据哪一列进行分组,那一列的列名。col2传入的是要将行转成列的那一列的列名,col3表示需要进行统计的数据列的列名
viewname传入希望建立的视图的名称,可以不填,默认为v_tmp
这么说很难让人明白..举个例子,引用一个帖子的数据

create table tab (
counter varchar(20), -- 参加考试人数
subject varchar(20), -- 科目
class varchar(20) -- 班级
)


表数据:

counter subject class
36 英语 一班
44 英语 二班
44 数学 二班
33 语文 一班
39 语文 三班


转换后:

一班 二班 三班
英语 36 44 0
数学 0 44 0
语文 33 0 39


编译好过程后,执行
begin
proc('tab','subject','class','counter');
end;

--结果
select * from v_tmp;

SUBJECT 一班 三班 二班
数学 44
英语 36 44
语文 33 39

如果对这个结果不是很满意,需要自己进行一些修改,比如空值的地方用0代替,或者需要用别的函数聚合而不是max。可以将过程中的execute immediate那句改成
dbms_output.put_line(sqlstr);
重新编译,执行,输出代码
如果用的是pl/sql dev的sql窗口,到output窗口查看
--看到生成的代码
create or replace view v_tmp as select subject
,max(decode(class,'一班',counter))"一班"
,max(decode(class,'三班',counter))"三班"
,max(decode(class,'二班',counter))"二班" from tab group by subject

再加入nvl(),达到修改的目的

如果不想创建这样一个过程,则改成匿名块,需要时运行
declare
tabname varchar2(20):='XXX';--'XXX'分别用相应的表名和字段名代替
col1 varchar2(10):='XXX';
col2 varchar2(10):='XXX';
col3 varchar2(10):='XXX';
viewname in varchar2(10):= 'v_tmp';
sqlstr varchar2(2000):='create or replace view '||viewname||' as select '||col1||' ';
c1 sys_refcursor;
v1 varchar2(100);
begin
open c1 for 'select distinct to_char('||col2||') from '||tabname;
loop
fetch c1 into v1;
exit when c1%notfound;
sqlstr:=sqlstr||'
,max(decode('||col2||','''||v1||''','||col3||'))"'||v1||'"';
end loop;
close c1;
sqlstr:=sqlstr||' from '||tabname||' group by '||col1;
--execute immediate sqlstr;
dbms_output.put_line(sqlstr);
end;

p.s.我对上面的过程进行了改进,参阅http://topic.csdn.net/u/20100109/13/6a10c168-f190-4766-b838-adbf03c4ac7b.html
...全文
2343 44 打赏 收藏 举报
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
baidiao 2011-03-31
  • 打赏
  • 举报
回复
我这里执行报错啊,哪位帮忙看看,错误截图如下:





ldzsl 2010-06-22
  • 打赏
  • 举报
回复
每天回帖即可获得10分可用分!小技巧
dzntree 2010-03-24
  • 打赏
  • 举报
回复
请问楼主列转行如何做呢??请教~~~
dzntree 2010-03-23
  • 打赏
  • 举报
回复
11g有个新特性,用PIVOT函数,以楼主的成绩表的例子,可以写成:
select * from tab
pivot(
sum(counter) for class in ('one' as one,'two' as two,'three' as three)
)
order by subject;
computer_2010 2010-03-12
  • 打赏
  • 举报
回复
学习!
bigzoom 2010-01-22
  • 打赏
  • 举报
回复
楼主用的哪个版本的数据库,我在SQL 2000里面运行怎么总是提示有很多错误呢?
小灰狼W 2010-01-22
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 jiasongmao850306 的回复:]
楼主用的哪个版本的数据库,我在SQL 2000里面运行怎么总是提示有很多错误呢?

[/Quote]
这是oracle的..如果要使用sqlserver需要进行一些修改
sxdgundam 2010-01-21
  • 打赏
  • 举报
回复
mark收藏!
啵比 2010-01-11
  • 打赏
  • 举报
回复
看看在学习...!
sjm5210 2010-01-11
  • 打赏
  • 举报
回复
好贴 我顶
huangya0 2010-01-11
  • 打赏
  • 举报
回复
标记一下
cougar0709 2010-01-11
  • 打赏
  • 举报
回复
辛苦了,收藏学习
liguominz 2009-12-11
  • 打赏
  • 举报
回复
收藏了,谢谢。
小灰狼W 2009-12-07
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 hebo2005 的回复:]
需要建视图啊
这样万一不断在变查询表,就会不断建视图,另外还需要用户有建视图的权限
[/Quote]
建视图是为了方便查询
只要表结构和需求不变,不用重新建视图啊。而且重新执行过程会覆盖原来的视图
权限确实是的,要创建视图的权限,不过这个问题应该不大
haixingfuyun 2009-12-01
  • 打赏
  • 举报
回复
看上去不错.,
tiancx82 2009-11-21
  • 打赏
  • 举报
回复
谢谢楼主,收藏了,帮助很大
notebook800 2009-11-21
  • 打赏
  • 举报
回复
瞻仰
hebo2005 2009-11-20
  • 打赏
  • 举报
回复
需要建视图啊
这样万一不断在变查询表,就会不断建视图,另外还需要用户有建视图的权限
voice007 2009-11-20
  • 打赏
  • 举报
回复
mark!
无忧工作室 2009-11-19
  • 打赏
  • 举报
回复
学习,收藏
加载更多回复(23)
源码链接: https://pan.quark.cn/s/a4b39357ea24 双系统引导修复机制是为那些在个人计算机上部署了两个操作系统(例如Windows与Linux、Windows的不同版本组合等)的用户群体量身定制的辅助程序。在常规操作过程中,由于某些因素的影响,比如系统更新、驱动程序安装或意外操作,可能会导致双系统的启动选择界面出现故障,无法正常选择需要启动的操作系统。在此情形下,需要一款操作极为简便的双系统启动菜单自动修正工具来处理这一挑战。 标题中所指的“双系统引导修复机制”指的是这一工具的核心作用,它专门致力于修复引导区域或MBR(主引导记录),而这两个部分是计算机在启动时用来加载操作系统的核心组件。引导修复过程通常包括对BIOS或UEFI设置进行校准,以及修复或重建BCD(启动配置数据)存储,这在Windows操作系统环境中显得尤为重要。 描述中提及的“操作简便修复”表明该工具在设计上非常注重易用性,无需用户拥有专业的计算机技术背景。用户只需遵循基础的步骤指引,即可自动完成启动菜单的修正任务,显著简化了故障诊断的流程。 标签“双系统启动菜单自动修复工具”进一步突出了该软件的主要职能,即解决因各种原因引发的双系统启动菜单失效状况。此类工具通常会对已安装的操作系统进行扫描,识别出所有可用的启动选项,并重新构建准确的引导菜单,使用户能够在启动阶段自由选择要执行的系统。 关于压缩文件内的“bootitng”文件,很可能是一个用于实施引导修复流程的程序组件。BootIt Next Generation(BING)是一个广为人知的引导管理解决方案,其部分模块可能以“bootitng”命名,负责处理启动项的管理与修复工作。该文件在执行修复过程中具有核...

17,133

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧