Oracle表或者视图的行转列[练习]
2014-07-19 10:08
369 查看
--行转列函数 2014年7月17日 16:15:18 Function Fn_Row_To_Col(tabname in varchar2, --需要进行行转列操作的表名或者视图; group_col in varchar2, --查询结果要按某列或某些列分组的字段名; column_col in varchar2, -- 要从行转成列的字段; value_col in varchar2, -- 需要聚合的值字段; Aggregate_func in varchar2 default 'max', -- 选用的聚合函数,可选,默认为max; colorder in varchar2 default null, -- 行转列后列的排序,可选; roworder in varchar2 default null, -- 行转列后记录的排序,可选; when_value_null in varchar2 default null,-- 若value_col字段的值聚合后为空,则转换成该值,可选; where_str in varchar2 default null,--对tabname的查询条件,可选 rowcount_str in varchar2 default null--,--对tabname进行行统计,可选(合计、2099-12-31) ) return sys_refcursor as sqlstr varchar2(4000) := 'select ' || group_col || ' '; c1 sys_refcursor; v1 varchar2(100); tempstr varchar2(4000):=''; rowsqlstr varchar2(4000):=''; cur sys_refcursor; begin If rowcount_str is not null then--如果tabname进行行统计的条件不为空则进行统计 rowsqlstr:=rowsqlstr||sqlstr||','||column_col||','||value_col||' from '||tabname||' '||where_str||' union '|| sqlstr||','''||rowcount_str||''' '||column_col||','||Aggregate_func||'('||value_col||') '||value_col||' from '||tabname ||' '||where_str||' group by '||group_col; tempstr:=tempstr||'select distinct ' || column_col || ' from ( '|| rowsqlstr||' ) '||(case when colorder is not null then ' order by ' || colorder end); Else tempstr:=tempstr||'select distinct ' || column_col || ' from ' || tabname||' '||where_str||(case when colorder is not null then ' order by ' || colorder end); End If; open c1 for tempstr; loop fetch c1 into v1; exit when c1%notfound; sqlstr := sqlstr || chr(10) || ',' || case when when_value_null is not null then 'nvl(' end || Aggregate_func || '(decode(to_char(' || column_col ||'),''' || v1 || ''',' || value_col || '))' || case when when_value_null is not null then chr(44) || when_value_null || chr(41) end || '"' || v1 || '"'; end loop; close c1; tempstr:=sqlstr || ' from ' || case when rowcount_str is not null then '( '||rowsqlstr||' )' else tabname end||' group by ' || group_col || case when roworder is not null then ' order by ' || roworder end; --DBMS_OUTPUT.put_line(length(tempstr));--查看是否超过4000个字符 open cur for tempstr; return cur; end Fn_Row_To_Col;
--执行查询 Select PKG_STM_GETDATA_TABLE.Fn_Row_To_Col(tabname =>'VW_DAYRPT_STDTSK_R', group_col => 'DPTKEY,DPTCNNAME,PARTKEY,PARTMCODE,PARTNAME,LABOURKEY,LABOURCODE,LABOURNAME', column_col => 'DAYRPTDATE', value_col => 'PRODTIME', aggregate_func =>'Sum', colorder =>'DAYRPTDATE asc', roworder =>'DPTKEY asc,LABOURCODE asc,PARTKEY asc', when_value_null =>null, where_str => ' where DAYRPTDATE>=''2014-05-28'' and DAYRPTDATE<=''2014-06-28''', rowcount_str => '合计') from dual;
备注:程序中可以使用存储过程
Procedure Sp_Row_To_Col(tabname in varchar2, --需要进行行转列操作的表名或者视图;
group_col in varchar2, --查询结果要按某列或某些列分组的字段名;
column_col in varchar2, -- 要从行转成列的字段;
value_col in varchar2, -- 需要聚合的值字段;
Aggregate_func in varchar2 default 'max', -- 选用的聚合函数,可选,默认为max;
colorder in varchar2 default null, -- 行转列后列的排序,可选;
roworder in varchar2 default null, -- 行转列后记录的排序,可选;
when_value_null in varchar2 default null,-- 若value_col字段的值聚合后为空,则转换成该值,可选;
where_str in varchar2 default null,--对tabname的查询条件,可选
rowcount_str in varchar2 default null,--对tabname进行行统计,可选(合计、2099-12-31)
cur out sys_refcursor--以游标的形式、返回数据集
)
as
sqlstr varchar2(4000) := 'select ' || group_col || ' ';
c1 sys_refcursor;
v1 varchar2(100);
tempstr varchar2(4000):='';
rowsqlstr varchar2(4000):='';
--cur sys_refcursor;
begin
If rowcount_str is not null then--如果tabname进行行统计的条件不为空则进行统计
rowsqlstr:=rowsqlstr||sqlstr||','||column_col||','||value_col||' from '||tabname||' '||where_str||' union '||
sqlstr||','''||rowcount_str||''' '||column_col||','||Aggregate_func||'('||value_col||') '||value_col||' from '||tabname
||' '||where_str||' group by '||group_col;
tempstr:=tempstr||'select distinct ' || column_col || ' from ( '|| rowsqlstr||' ) '||(case when colorder is not null then ' order by ' || colorder end);
Else
tempstr:=tempstr||'select distinct ' || column_col || ' from ' || tabname||' '||where_str||(case when colorder is not null then ' order by ' || colorder end);
End If;
open c1 for tempstr;
loop fetch c1 into v1;
exit when c1%notfound;
sqlstr := sqlstr || chr(10) || ',' || case when when_value_null is not null then
'nvl(' end || Aggregate_func || '(decode(to_char(' || column_col ||'),''' || v1 || ''',' || value_col || '))'
|| case when when_value_null is not null then chr(44) || when_value_null || chr(41) end || '"' || v1 || '"';
end loop;
close c1;
tempstr:=sqlstr || ' from ' || case when rowcount_str is not null then '( '||rowsqlstr||' )' else tabname end||' group by ' || group_col || case when roworder is not null then ' order by ' || roworder end;
--DBMS_OUTPUT.put_line(length(tempstr));--查看是否超过4000个字符
open cur for tempstr;
end Sp_Row_To_Col;
相关文章推荐
- Oracle 行转列 万能视图
- oracle 是user_tables里面可以查找到一个表,而用DESC或者insert语句插入时就会报不存在视图。
- 我的Oracle 9i学习日志(9)--数据字典与动态性能视图及练习
- oracle判断视图或者表名存在删除不存在不删除
- oracle 表或者视图不存在,名称已由现有对象使用,可是又查询到数据
- oracle 导入数据库脚本后,有些视图或者存储过程没有自动编译的批量解决方式
- Oracle查看表或者视图的定义语句
- oracle学习—视图、序列、索引、约束练习
- PD12逆向工程从Oracle10中生成,出现ORA-00942 表或者视图不存在错误
- 查看Oracle有哪些表或者视图
- Oracle动态性能视图 v$sga 学习笔记
- ORACLE中表,视图名变大写和BLOB操作的问题
- ORACLE里取随机数的方法,随机取出一些符合条件的EMAIL或者手机号码用户
- Oracle如何实现利用实体化视图提高查询性能
- Oracle的实体化视图(MVIEW)的深入研究之四
- SQL 优化之 oracle物化视图
- Oracle的实体化视图(MVIEW)的深入研究之一
- Oracle的视图、同义词、序列
- SQL92,SQL SERVER,ORACLE,DB2可更新视图概述
- Oracle中向视图中插入数据