1.使用视图

SQL code?
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
create or replace procedure row_to_col(tabname in varchar2,
                                  group_col in varchar2,
                                  column_col in varchar2,
                                  value_col in varchar2,
                                  Aggregate_func in varchar2 default 'max',
                                  colorder in varchar2 default null,
                                  roworder in varchar2 default null,
                                  when_value_null in varchar2 default null,
                                  viewname in varchar2 default 'v_tmp')
Authid Current_User
as
  sqlstr varchar2(2000):='create or replace view '||viewname||' as select '||group_col||' ';
  c1 sys_refcursor;
  v1 varchar2(100);
begin
  open c1 for 'select distinct '||column_col||' from '||tabname||case when colorder is not null then ' order by '||colorder end;
  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;
  sqlstr:=sqlstr||' from '||tabname||' group by '||group_col||case when roworder is not null then ' order by '||roworder end;
  execute immediate sqlstr;
end row_to_col;

这里修改了传入参数名,使其更容易理解。继续使用了创建视图这个方法,当然也可以改成用游标传出。
参数:
tabname 需要进行行转列操作的表名;
group_col 查询结果要按某列或某些列分组的字段名;
column_col 要从行转成列的字段;
value_col 需要聚合的值字段;
Aggregate_func 选用的聚合函数,可选,默认为max;
colorder 行转列后列的排序,可选;
roworder 行转列后记录的排序,可选;
when_value_null 若value_col字段的值聚合后为空,则转换成该值,可选;
viewname 创建的视图名称,可选,默认为v_tmp。

举例:

SQL code?
1
2
3
4
5
6
7
8
9
10
11
--测试数据
create table rowtocol_test as
select 2009 year,1 month,'部门1' dept,50000 expenditure from dual
union all select 2009,2,'部门1',20000 from dual
union all select 2009,2,'部门1',30000 from dual
union all select 2010,1,'部门1',35000 from dual
union all select 2009,2,'部门2',40000 from dual
union all select 2009,3,'部门2',25000 from dual
union all select 2010,2,'部门3',60000 from dual
union all select 2009,2,'部门3',15000 from dual
union all select 2009,2,'部门3',10000 from dual;

我现在想根据year和month分组,将部门转成列。

SQL code?
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
29
30
31
SQL> select from rowtocol_test;
  
      YEAR      MONTH DEPT  EXPENDITURE
---------- ---------- ----- -----------
      2009          1 部门1       50000
      2009          2 部门1       20000
      2009          2 部门1       30000
      2010          1 部门1       35000
      2009          2 部门2       40000
      2009          3 部门2       25000
      2010          2 部门3       60000
      2009          2 部门3       15000
      2009          2 部门3       10000
  
rows selected
  
SQL> execute row_to_col('rowtocol_test','year,month','dept','expenditure');
 
PL/SQL procedure successfully completed
  
SQL> select from v_tmp;
  
      YEAR      MONTH        部门1        部门3        部门2
---------- ---------- ---------- ---------- ----------
      2009          1      50000            
      2010          1      35000            
      2009          3                            25000
      2009          2      30000      15000      40000
      2010          2                 60000 
  
SQL> 

这个结果可能不是我们想要的,重新调用过程,使用几个可选参数

SQL code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SQL> execute row_to_col('rowtocol_test','year,month','dept','expenditure',Aggregate_func => 'sum',colorder => 'dept',roworder => '1,2',when_value_null => '0');
  
PL/SQL procedure successfully completed
  
SQL> select from v_tmp;
  
      YEAR      MONTH        部门1        部门2        部门3
---------- ---------- ---------- ---------- ----------
      2009          1      50000          0          0
      2009          2      50000      40000      25000
      2009          3          0      25000          0
      2010          1      35000          0          0
      2010          2          0          0      60000
  
SQL> 

进行行转列的也可以是视图

SQL code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SQL> create view view_rowtocol as select from rowtocol_test where year=2009;
  
View created
  
SQL> execute row_to_col('view_rowtocol','year,month','dept','expenditure',Aggregate_func => 'sum',colorder => 'dept',roworder => '1,2',when_value_null => '0');
  
PL/SQL procedure successfully completed
  
SQL> select from v_tmp;
  
      YEAR      MONTH        部门1        部门2        部门3
---------- ---------- ---------- ---------- ----------
      2009          1      50000          0          0
      2009          2      50000      40000      25000
      2009          3          0      25000          0
  
SQL> 

-----------------------------------------------------------
2.稍加修改,使用函数,返回游标。或利用过程里的传出参数

SQL code?
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 row_to_col_func(tabname in varchar2,
                                  group_col in varchar2,
                                  column_col in varchar2,
                                  value_col in varchar2,
                                  Aggregate_func in varchar2 default 'max',
                                  colorder in varchar2 default null,
                                  roworder in varchar2 default null,
                                  when_value_null in varchar2 default null
                                  )return sys_refcursor
Authid Current_User
as
  sqlstr varchar2(2000):='select '||group_col||' ';
  c1 sys_refcursor;
  v1 varchar2(100);
  cur sys_refcursor;
begin
  open c1 for 'select distinct '||column_col||' from '||tabname||case when colorder is not null then ' order by '||colorder end;
  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;
  open cur for sqlstr||' from '||tabname||' group by '||group_col||case when roworder is not null then ' order by '||roworder end;
  return cur;
end row_to_col_func;

在pl/sql dev中可以在sql窗口执行,查看结果

SQL code?
1
2
3
4
5
6
7
8
9
10
11
12
13
select 
row_to_col_func('rowtocol_test','year,month','dept','expenditure',Aggregate_func => 'sum',colorder => 'dept',roworder => '1,2',when_value_null => '0')
from dual;
 
ROW_TO_COL_FUNC('ROWTOCOL_TEST
<Cursor>
 
YEAR    MONTH    部门1    部门2    部门3
2009    1    50000    0        0
2009    2    50000    40000    25000
2009    3    0        25000    0
2010    1    35000    0        0
2010    2    0        0        60000

原文:http://bbs.csdn.net/topics/330039676

ORACLE行转列通用过程(转)的更多相关文章

  1. ORACLE行转列通用过程

    create or replace procedure row_to_col(tabname in varchar2,                                   group_ ...

  2. oracle 行转列 分析函数

    oracle 行转列 首先看一下源数据: 方法一:WM_CONCAT group by 这个方法没有问题. SELECT CODE_TS, WMSYS.WM_CONCAT(S_NUM + || ':' ...

  3. Oracle 行转列pivot 、列转行unpivot 的Sql语句总结

    这个比较简单,用||或concat函数可以实现 select concat(id,username) str from app_user select id||username str from ap ...

  4. ORACLE 行转列的通用过程

    --测试数据create table rowtocol_test asselect 2009 year,1 month,'部门1' dept,50000 expenditure from dualun ...

  5. Oracle 行转列 动态出转换的列

    本文链接:https://blog.csdn.net/Huay_Li/article/details/82924443 10月的第二天,前天写了个Oracle中行转列的pivot的基本使用方法,然后, ...

  6. oracle行转列、列转行、连续日期数字实现方式及mybatis下实现方式

    转载请注明出处:https://www.cnblogs.com/funnyzpc/p/9977591.html 九月份复习,十月份考试,十月底一直没法收心,赶在十一初 由于不可抗拒的原因又不得不重新找 ...

  7. Oracle行转列LISTAGG函数

    工作过程中需要将查询的数据分组并显示在一行.以往的工作经验,在sql server中可以用for xml path来实现. 现提供Oracle数据库的行转列方式 oracle11g官方文档简介如下: ...

  8. Oracle行转列、列转行的Sql语句总结

    多行转字符串 这个比较简单,用||或concat函数可以实现  SQL Code  12    select concat(id,username) str from app_userselect i ...

  9. Oracle行转列、列转行的Sql语句总结(转)

    多行转字符串 这个比较简单,用||或concat函数可以实现 select concat(id,username) str from app_userselect id||username str f ...

随机推荐

  1. CodeForces - 767A Snacktower

    题目大意 一个数可以被输出当且仅当所有比它大的数都已经输出.输入一个1~n的排列,求每次输出的输出序列. 题解 直接用堆模拟 #include <queue> #include <c ...

  2. Trie 树内存消耗问题

    大家都知道,Trie树(又称字典树)是一种树型数据结构,用于保存大量的字符串.它的优点是:利用字符串的公共前缀来节约存储空间. 相对来说,Trie树是一种比较简单的数据结构,比较易于理解.话说上帝是公 ...

  3. bzoj 1731 [Usaco2005 dec]Layout 排队布局——差分约束

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1731 对差分约束理解更深.还发现美妙博客:http://www.cppblog.com/me ...

  4. Jmeter提取响应数据的结果保存到本地的一个文件

    原文地址: https://www.cnblogs.com/whitewasher/p/9504728.html 当做性能压测时,可能会需要把响应数据的一些字段统计出来.这里简单介绍一下. 1.首先把 ...

  5. 云-资讯-Micron-Insight:云的形成方式 — 以及它的发展方向

    ylbtech-云-资讯-Micron-Insight:云的形成方式 — 以及它的发展方向 1.返回顶部 1. 云的形成方式 — 以及它的发展方向 当你坐下来开始一天工作的时候,你可能不会考虑到你所做 ...

  6. Spring入门第十一课

    IOC容器中Bean的生命周期 Spring IOC容器可以管理Bean的生命周期,Spring允许在Bean生命周期的特定点执行定制的任务. Spring IOC容器对Bean的生命周期进行管理的过 ...

  7. Razor的主版页面框架

    类似于2.0版本中的MasterPage主版页面框架,不过mvc3.0推出的RazorView内建的主版页面语法与原本的webFormview的MasterPage相差甚远   1,Razor的页面执 ...

  8. OpenGL学习笔记——求值器和NURBS

    http://codercdy.com/openglxue-xi-bi-ji-qiu-zhi-qi-he-nurbs/ 在最底层,图形硬件所绘制的是点.直线和多边形(通常是三角形和四边形).平滑的曲线 ...

  9. C 语言实例 - 判断正数/负数

    C 语言实例 - 判断正数/负数 用户输入一个数字,判断该数字是正数还是负数或是零. 实例 #include <stdio.h> int main() { double number; p ...

  10. Jmeter集成Jira提交缺陷

    笔者曾在文章<Jmeter排忧解难—生成excel结果文件>聊到了一种提高接口测试效率的方法.今天,咱们接着对“提高接口测试效率”这个话题做更深入的探讨.作为一名接口测试人员,我们是否一直 ...