原始需求,有2表如下

SQL> select * from mas;

TO TOOLNAME

-- ----------

01 包裹

02 信函

03 挂号信

04 中国速递

05 EMS

06 DHL

6 rows selected.

SQL> select * from putdt;

SENDDT TO GNAME ST CITY

-------- -- ---------- -- ----

20070101 01 john 12 2566

20070101 04 david 16 3098

20070101 05 apple 18 2098

20070201 04 apple 16 3078

20070304 05 poly 13 1001

20070304 04 john 12 2566

20070101 01 james 12 8800

7 rows selected.

要求输出如下格式的报表

senddt toolid1 sum1 toolid2 sum2 toolid3 sum3 toolid4 sum4 toolid5 sum5

20070101 01 1 02 0 03 0 04 1 05 1

20070201 01 0 02 0 03 0 04 1 05 0

20070304 01 0 02 0 03 0 04 1 05 1

即以senddt和toolid分组后的count数

每行显示一个senddt,但是列数是不确定的,根据表mas的toolid来定的

基本思路如下,如下的SQL 是动态构造的,其中的列数不确定,根据mas的toolid来定

select senddt,

max(toolid1) toolid1,max(sum1) sum1,

max(toolid2) toolid2,max(sum2) sum2,

max(toolid3) toolid3,max(sum3) sum3,

max(toolid4) toolid4,max(sum4) sum4,

max(toolid5) toolid5,max(sum5) sum5

from (select b.senddt,

'01' toolid1,

case when a.toolid=b.toolid and b.toolid='01' then b.sum_c else 0 end sum1,

'02' toolid2,

case when a.toolid=b.toolid and b.toolid='02' then b.sum_c else 0 end sum2,

'03' toolid3,

case when a.toolid=b.toolid and b.toolid='03' then b.sum_c else 0 end sum3,

'04' toolid4,

case when a.toolid=b.toolid and b.toolid='04' then b.sum_c else 0 end sum4,

'05' toolid5,

case when a.toolid=b.toolid and b.toolid='05' then b.sum_c else 0 end sum5

from mas a,

(select senddt,toolid,count(*) sum_c from putdt group by senddt,toolid) b)

group by senddt

order by senddt

测试用的存储过程

create or replace procedure test

as

v_column varchar2(5) := '';

v_sql_0 varchar2(10000) := '';

v_sql_1 varchar2(10000) := '';

p_fields varchar2(10000) := '';

begin

for t in (select toolid from mas order by toolid) loop

v_column := to_char(to_number(t.toolid));

v_sql_0 := v_sql_0||',max(toolid'||v_column||') toolid'||v_column||',max(sum'||v_column||') sum'||v_column;

v_sql_1 := v_sql_1||','''||t.toolid||''' toolid'||v_column||', case when a.toolid=b.toolid and b.toolid='''||t.toolid||''' then b.sum_c else 0 end sum'||v_column;

p_fields := p_fields||',toolid'||v_column||',sum'||v_column;

end loop;

v_sql_1 := 'select senddt'||v_sql_0||' from (select b.senddt'||v_sql_1||' from mas a,(select senddt,toolid,count(*) sum_c from putdt group by senddt,toolid) b) group by senddt order by senddt';

p_fields := ltrim(p_fields,',');

--open p_rs for v_sql_1;

dbms_output.put_line(v_sql_1);

end;

/

--------------

1. 建立package

--------------

create or replace package pkg_test

as

type cursor_fount100 is ref cursor;

procedure rs_fount100 (p_fields in out varchar2,p_rs in out cursor_fount100);

end;

/

create or replace package body pkg_test

as

procedure rs_fount100 (p_fields in out varchar2,p_rs in out cursor_fount100)

is

v_column varchar2(5) := '';

v_sql_0 varchar2(10000) := '';

v_sql_1 varchar2(10000) := '';

begin

for t in (select toolid from mas order by toolid) loop

v_column := to_char(to_number(t.toolid));

v_sql_0 := v_sql_0||',max(toolid'||v_column||') toolid'||v_column||',max(sum'||v_column||') sum'||v_column;

v_sql_1 := v_sql_1||','''||t.toolid||''' toolid'||v_column||', case when a.toolid=b.toolid and b.toolid='''||t.toolid||''' then b.sum_c else 0 end sum'||v_column;

p_fields := p_fields||',toolid'||v_column||',sum'||v_column;

end loop;

v_sql_1 := 'select senddt'||v_sql_0||' from (select b.senddt'||v_sql_1||' from mas a,(select senddt,toolid,count(*) sum_c from putdt group by senddt,toolid) b) group by senddt order by senddt';

p_fields := ltrim(p_fields,',');

open p_rs for v_sql_1;

end;

end;

/

----------------------------

2. JAVA程序 test.java 演示用

----------------------------

import java.io.*;

import java.text.*;

import java.lang.String;

import java.util.*;

import java.util.regex.*;

import java.lang.*;

import java.sql.*;

import oracle.sql.*;

import oracle.jdbc.driver.*;

public class test

{

public static void main(String[] args) throws Exception

{

String record_str="";

String field_list="";

String[] fields=null;

Pattern p = Pattern.compile(",");

Matcher m1;

OracleCallableStatement cstmt = null;

ResultSet rs = null;

DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());

Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.1:1521:实例名","数据库用户","密码");

cstmt = (OracleCallableStatement)conn.prepareCall("begin pkg_test.rs_fount100(?,?); end;");

cstmt.registerOutParameter(1,OracleTypes.VARCHAR);

cstmt.registerOutParameter(2,OracleTypes.CURSOR);

cstmt.execute();

field_list = cstmt.getString(1);

rs = (ResultSet)cstmt.getObject(2);

fields=p.split(field_list);

for(int i=0; i{

record_str=record_str+fields[i]+" ";

}

System.out.println("senddt "+record_str);

while (rs.next())

{

record_str="";

for(int f=1; f<=fields.length+1; f++)

{

record_str=record_str+rs.getString(f)+" ";

}

System.out.println(record_str);

}

rs.close();

cstmt.close();

conn.close();

}

}

---------------

3. 编译java程序

---------------

javac test.java

---------------

4. 演示1

---------------

SQL> select * from mas;

TO TOOLNAME

-- ----------

01 包裹

02 信函

03 挂号信

04 中国速递

05 EMS

SQL> select * from putdt;

SENDDT TO GNAME ST CITY

-------- -- ---------- -- ----

20070101 01 john 12 2566

20070101 04 david 16 3098

20070101 05 apple 18 2098

20070201 04 apple 16 3078

20070304 05 poly 13 1001

20070304 04 john 12 2566

6 rows selected.

E:>java test

senddt toolid1 sum1 toolid2 sum2 toolid3 sum3 toolid4 sum4 toolid5 sum5

20070101 01 1 02 0 03 0 04 1 05 1

20070201 01 0 02 0 03 0 04 1 05 0

20070304 01 0 02 0 03 0 04 1 05 1

---------------

5. 演示2

---------------

SQL> insert into putdt values('20070101','01','james','12','8800');

1 row created.

SQL> commit;

Commit complete.

SQL> select * from putdt;

SENDDT TO GNAME ST CITY

-------- -- ---------- -- ----

20070101 01 john 12 2566

20070101 04 david 16 3098

20070101 05 apple 18 2098

20070201 04 apple 16 3078

20070304 05 poly 13 1001

20070304 04 john 12 2566

20070101 01 james 12 8800

7 rows selected.

E:>java test

senddt toolid1 sum1 toolid2 sum2 toolid3 sum3 toolid4 sum4 toolid5 sum5

20070101 01 2 02 0 03 0 04 1 05 1

20070201 01 0 02 0 03 0 04 1 05 0

20070304 01 0 02 0 03 0 04 1 05 1

---------------

6. 演示3

---------------

SQL> insert into mas values('06','DHL');

1 row created.

SQL> commit;

Commit complete.

SQL> select * from mas;

TO TOOLNAME

-- ----------

01 包裹

02 信函

03 挂号信

04 中国速递

05 EMS

06 DHL

6 rows selected.

SQL> select * from putdt;

SENDDT TO GNAME ST CITY

-------- -- ---------- -- ----

20070101 01 john 12 2566

20070101 04 david 16 3098

20070101 05 apple 18 2098

20070201 04 apple 16 3078

20070304 05 poly 13 1001

20070304 04 john 12 2566

20070101 01 james 12 8800

7 rows selected.

E:java test

senddt toolid1 sum1 toolid2 sum2 toolid3 sum3 toolid4 sum4 toolid5 sum5 toolid6 sum6

20070101 01 2 02 0 03 0 04 1 05 1 06 0

20070201 01 0 02 0 03 0 04 1 05 0 06 0

20070304 01 0 02 0 03 0 04 1 05 1 06 0[@more@]

mysql 多行转换多列 列不确定_多行转多列,行数和列数不确定相关推荐

  1. hive 行转列和列转行的方法_面试常考!SQL行转列和列转行

    关注上方"数据挖掘工程师",选择星标,关键时间,第一时间送达!行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SE ...

  2. java数组是行优先还是列优先的语言_详解C语言数组中是以列优先吗

    如果我们按照C语言的方式存储它,也就是行优先存储的话,那么在内存中,它的形状是这样的: 这种存储方式又被称作C contiguous array. C语言数组结构列优先顺序存储的实现 (GCC编译). ...

  3. C#.Net工作笔记019---葡萄城控件FlexGrid自定义风格_比如给某列设置某个颜色_该颜色不受选择行的影响

    技术交流QQ群[JAVA,C,.NET,BigData,AI]:170933152 项目中有个需求,就是,前两列,需要固定住,但是我们都知道固定列是,作为表的title部分的,也就是不能写入文字的, ...

  4. Mysql要在表s中增加一列可用什么语句_要在基本表S中增加一列CN(课程名),可用语句()_学小易找答案...

    [填空题]在SQL中,要删除一个表,应使用的语句是( )TABLE. [单选题]精神检查的方法主要有( ) [单选题]护士从病人的书信.日记了解病人的情况是属于( ) [单选题]显示当前所有数据库的命 ...

  5. mysql 列转行union all_SQL查询案例:列行转换[列转行, 使用 UNION ALL 处理]

    SQL查询案例:列行转换[列转行, 使用 UNION ALL 处理] 在行列转换的处理之后, 有时候会遇到,要列行装换的 CREATE TABLE TestColRow ( name   VARCHA ...

  6. mysql 列转行union all_SQL查询案例:列行转换[列转行, 使用 UNION ALL 处理] | 学步园...

    SQL查询案例:列行转换[列转行, 使用 UNION ALL 处理] 在行列转换的处理之后, 有时候会遇到,要列行装换的 CREATE TABLE TestColRow ( name   VARCHA ...

  7. ORACLE-024:列行转换、多行合并

    当我们想把多列内容处理为一行,或者想把多行内容中按相同列名汇总都可以使用.使用的函数为LISTAGG. 比如如下sql, SELECT '你的常用英雄' 项目,'程咬金' 内容 from dualun ...

  8. awk取文本列_awk命令结构/内置变量/获取文本某行或某列

    awk脚本基本结构 awk 'BEGIN{ print "start" }pattern{ commands }END{ print "end" }' file ...

  9. Pandas行数和列数获取

    一.df的行数和列数获取 def del_pd_data(panda):count = 0data = []nums = panda.shapefor i in range(0, nums[1]):l ...

  10. 【数据库】sqlite中的限制:数据库大小、表数、列数、行数、参数个数、连接数等

    目录 一.参考网址 二.详解 1.查看.设置sqlite限制命令.limit 2.SQLite中的限制汇总 1)字符串或BLOB的最大长度 2)最大列数 3)SQL语句的最大长度 4)联接中的最大表数 ...

最新文章

  1. Linux_Shell基础
  2. 五年之后的私有云和公有云会是什么样子
  3. java web怎么样_怎么样自学Java web?
  4. 组播理论知识的补充笔记
  5. vmware安装ubuntu13版本的vm tools时遇到的错误解决
  6. neo-6m uno_Uno-统治所有人的平台
  7. java拉丁正方形_LeetCode JAVA解题---824. 山羊拉丁文
  8. P3194 [HNOI2008]水平可见直线
  9. 公司这套架构统一处理try...catch这么香,求求你不要再满屏写了,再发现扣绩效!...
  10. c++项目实例_.NET Core CLI来启动应用程序的多个实例
  11. Java学习步骤及路线(超详细)
  12. openGL之API学习(一四七)实时渲染、光线追踪渲染和栅格化渲染
  13. SharePoint 2013 SqlException (0x80131904):找不到Windows NT 用户或组xxxx\administrator
  14. 非服务器模式下运行getImageData函数出现 the operation is insecure
  15. 电磁场有限元基本原理(1)边界条件
  16. 深信服python开发工程师面试经验,深信服软件工程师面试经验
  17. 打赢防“疫”战,云服务商都做了什么……
  18. python小程序模板——阿龙的小百宝箱
  19. 对抗样本生成算法复现代码解析:FGSM和DeepFool
  20. Moment.js 用法

热门文章

  1. python代码实现插入排序
  2. 使用String()解决utf-8字符转GB2312的问题
  3. 贝叶斯统计的无信息先验和共轭先验
  4. 短序列拼接软件velvet简介
  5. 保证计算机网络的稳定运行,厦门大学校园网管理保证网络稳定运行
  6. android中仿qq最新版抽屉,Android实现3种侧滑效果(仿qq侧滑、抽屉侧滑、普通侧滑)...
  7. windows10安装docker
  8. jquery 实现仿QQ右下角弹出框
  9. linux-dash安装和使用
  10. perl 连接mysql_perl如何连接mysql数据库?