demo场景,以oracle自带库中的表emp为例:

  select ename,deptno from emp order by deptno;

ENAME DEPTNO
CLARK 10
KING 10
MILLER 10
SMITH 20
ADAMS 20
FORD 20
SCOTT 20
JONES 20
ALLEN 30
BLAKE 30
MARTIN 30
JAMES 30
TURNER 30
WARD 30

现在想要将同一部门的人给合并成一行记录,如何做呢?如下:

ENAME DEPTNO
CLARK,KING,MILLER 10
ADAMS,FORD,JONES,SCOTT,SMITH 20
ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD 30

  通常我们都是自己写函数或在程序中处理,这里我们利用oracle自带的分析函数row_number()和sys_connect_by_path来进行sql语句层面的多行到单行的合并,并且效率会非常高。

  基本思路:

  1、对deptno进行row_number()按ename排位并打上排位号

  select deptno,ename,row_number() over(partition by deptno order by deptno,ename) rank

  from emp order by deptno,ename;

DEPTNO ENAME RANK
10 CLARK 1
10 KING 2
10 MILLER 3
20 ADAMS 1
20 FORD 2
20 JONES 3
20 SCOTT 4
20 SMITH 5
30 ALLEN 1
30 BLAKE 2
30 JAMES 3
30 MARTIN 4
30 TURNER 5
30 WARD 6

  可看出,经过row_number()后,部门人已经按部门和人名进行了排序,并打上了一个位置字段rank

2、利用oracle的递归查询connect by进行表内递归,并通过sys_connect_by_path进行父子数据追溯串的构造,这里要针对ename字段进行构造,使之合并在一个字段内(数据很多,只截取部分)

  select deptno,ename,rank,level as curr_level,

  ltrim(sys_connect_by_path(ename,','),',') ename_path from (

  select deptno,ename,row_number() over(partition by deptno order by deptno,ename) rank

  from emp order by deptno,ename) connect by deptno = prior deptno and rank-1 = prior rank;

  各部门递归后的数据量都是:(1+n)/2 * n 即:deptno=10 数据量:(1+3)/2 * 3 = 6;

  deptno=20 数据量:(1+5)/2 * 5 = 15;      deptno=30 数据量:(1+6)/2 * 6 = 21;

DEPTNO ENAME RANK CURR_LEVEL ENAME_PATH
10 CLARK 1 1 CLARK
10 KING 2 2 CLARK,KING
10 MILLER 3 3 CLARK,KING,MILLER
10 KING 2 1 KING
10 MILLER 3 2 KING,MILLER
10 MILLER 3 1 MILLER
DEPTNO ENAME RANK CURR_LEVEL ENAME_PATH
20 ADAMS 1 1 ADAMS
20 FORD 2 2 ADAMS,FORD
20 JONES 3 3 ADAMS,FORD,JONES
20 SCOTT 4 4 ADAMS,FORD,JONES,SCOTT
20 SMITH 5 5 ADAMS,FORD,JONES,SCOTT,SMITH
20 FORD 2 1 FORD
20 JONES 3 2 FORD,JONES
20 SCOTT 4 3 FORD,JONES,SCOTT
20 SMITH 5 4 FORD,JONES,SCOTT,SMITH
20 JONES 3 1 JONES
20 SCOTT 4 2 JONES,SCOTT
20 SMITH 5 3 JONES,SCOTT,SMITH
20 SCOTT 4 1 SCOTT
20 SMITH 5 2 SCOTT,SMITH
20 SMITH 5 1 SMITH

  这里我们仅列出deptno=10、20的,至此我们应该能否发现一些线索了,即每个部门中,curr_level最高的那行,有我们所需要的数据。那后面该怎么办,取出那个数据? 对了,继续用row_number()进行排位标记,然后再按排位标记取出即可。

  3、 对deptno继续进行row_number()按curr_level排位

  select deptno,ename_path,row_number() over(partition by deptno order by deptno,curr_level desc) ename_path_rank from (select deptno,ename,rank,level as curr_level,

  ltrim(sys_connect_by_path(ename,','),',') ename_path from (

  select deptno,ename,row_number() over(partition by deptno order by deptno,ename) rank

  from emp order by deptno,ename) connect by deptno = prior deptno and rank-1 = prior rank);

DEPTNO ENAME_PATH ENAME_PATH_RANK
10 CLARK,KING,MILLER 1
10 CLARK,KING 2
10 KING,MILLER 3
10 CLARK 4
10 KING 5
10 MILLER 6
DEPTNO ENAME_PATH ENAME_PATH_RANK
20 ADAMS,FORD,JONES,SCOTT,SMITH 1
20 ADAMS,FORD,JONES,SCOTT 2
20 FORD,JONES,SCOTT,SMITH 3
20 ADAMS,FORD,JONES 4
20 FORD,JONES,SCOTT 5
20 JONES,SCOTT,SMITH 6
20 ADAMS,FORD 7
20 FORD,JONES 8
20 SCOTT,SMITH 9
20 JONES,SCOTT 10
20 ADAMS 11
20 JONES 12
20 SMITH 13
20 SCOTT 14
20 FORD 15

  这里还是仅列出deptno为10、20的,至此应该很明了了,在进行一次查询,取ename_path_rank为1的即可获得我们想要的结果。

  4、获取想要排位的数据,即得部门下所有人多行到单行的合并

  select deptno,ename_path from (select deptno,ename_path,

  row_number() over(partition by deptno order by deptno,curr_level desc) ename_path_rank

  from (select deptno,ename,rank,level as curr_level,

  ltrim(sys_connect_by_path(ename,','),',') ename_path from (

  select deptno,ename,row_number() over(partition by deptno order by deptno,ename) rank

  from emp order by deptno,ename) connect by deptno = prior deptno and rank-1 = prior rank))

  where ename_path_rank=1;

select deptno, ename_pathfrom (select deptno,ename_path,row_number() over(partition by deptno order by deptno, curr_level desc) ename_path_rankfrom (/*key sub query,自连接构造树*/select       empno,     deptno,ename,rank,level as curr_level,ltrim(sys_connect_by_path(ename, ','), ',') ename_pathfrom (select deptno,ename,empno,row_number() over(partition by deptno order by deptno, ename) rankfrom emporder by deptno, ename)connect by deptno = prior deptnoand rank - 1 = prior rank/*end query*/ ))  where ename_path_rank = 1;

—————————————————————————————————————————————————
查询表中的一个字段,返回了多行,就把这么多行的数据都拼成一个字符串。

例:   id  name
       1   aa
       2   bb
       3   cc

要的结果是"aa,bb,cc"


select WMSYS.WM_CONCAT(a.name) from user a

这样的话,查询出的结果:"aa.bb.cc"

中间用点间隔,如果想替换为其他符号,例如用逗分号

select replace(WMSYS.WM_CONCAT(a.name),',',';') from user a

结果:"aa;bb;cc"

转载于:https://www.cnblogs.com/ryb/archive/2012/12/20/2825980.html

利用Oracle分析函数实现多行数据合并为一行相关推荐

  1. Oracle多行数据合并成一行

    Oracle多行数据合并成一行 一.listagg 函数------(有长度限制) SELECT listagg(待拼接字段, ',') within group(ORDER BY 待拼接字段) AS ...

  2. sqlserver函数多行数据合并成一行

    sqlserver函数多行数据合并成一行 SELECTusername,coursename= (STUFF((SELECT ',' + coursenameFROM t_user_courseWHE ...

  3. 各数据库SQL查询结果多行数据合并成一行

    SQL查询结果多行数据合并成一行 一.Oracle函数多行数据合并成一行 二.Mysql函数多行数据合并成一行 三.sqlserver函数多行数据合并成一行 四.postgresql函数多行数据合并成 ...

  4. java 合并到一行_mysql中将多行数据合并成一行数据

    一个字段可能对应多条数据,用mysql实现将多行数据合并成一行数据 例如:一个活动id(activeId)对应多个模块名(modelName),按照一般的sql语句: 1 SELECT am.acti ...

  5. mysql大量数据合并_mysql中将多行数据合并成一行数据

    一个字段可能对应多条数据,用mysql实现将多行数据合并成一行数据 例如:一个活动id(activeId)对应多个模块名(modelName),按照一般的sql语句: 1 SELECT am.acti ...

  6. python如何输入多行数据合并_Python如何将多行数据合并成一行|python如何实现excle数据合并...

    用Python导出工程文件两个子页里的数据成为两个excel表格,但我想把它合并成个一个excel表格的两个sheet 可以采用一些Excel的模块去实现,比如xlrd.xlwt.openpyxl.x ...

  7. Excel如何将多行数据合并为一行并添加间隔符号

    今天小编跟大家分享一下Excel如何将多行数据合并为一行 1.打开要合并的Excel文件 2.选中要合并的单元格区域 3.然后点击下图选项(Excel工具箱,百度即可了解详细下载安装信息,本文这里就不 ...

  8. STUFF()函数将查询的多行数据合并为一行

    一.stuff函数 (一)说明 STUFF()函数用于删除指定长度的字符,并可以在制定的起点处插入另一组字符. (二)函数 STUFF ( character_expression , start , ...

  9. linux 将多行数据合并为一行

    文章目录 linux 将多行数据合并为一行 需求说明: 解决方法: tr 命令 xargs 命令 awk命令 linux 将多行数据合并为一行 需求说明: 在一些情况下需要将一个文件中的多行数据合并到 ...

最新文章

  1. java web 嵌套播放器_网页嵌套播放器
  2. Linux驱动入门篇(一):Hello, world
  3. 如何确定h.264的码率
  4. 剑指Offer - 面试题61. 扑克牌中的顺子
  5. shell的read方法使用介绍
  6. 拼接字符串时的引号嵌套
  7. python下载-python下载及安装
  8. Oracle odi 数据表导出到文件
  9. C++中result_of用法
  10. 计算机图形学的边表教学ppt,计算机图形学(多边形的扫描转换).ppt
  11. Windows PE(WinPE)
  12. URL中文参数错误解决方法
  13. 疫情期间,找工作的一些建议
  14. 房地产开发建设项目管理(全程房地产典范企业案例)
  15. 黑暗森林法则和猜疑链同样存在人和人之间
  16. 微信小程序:升级版手机检测微信工具小程序源码
  17. excel怎么设置自动计算_EXCEL内输入起始时间,如何自动计算小时时间差?
  18. 72.全卷积神经网络(FCN)及代码实现
  19. java操作office和pdf文件java读取word,excel和pdf文档内容
  20. 市审计局充分利用大数据助力扶贫和“十个全覆盖”审计工作

热门文章

  1. java存款程序_JAVA实现账户取款和存款操作
  2. center6linux ip设置,centos6固定ip地址
  3. mysql 连接 优化_(一)MySQL 连接优化
  4. 画一个空心圆_用SolidWorks画一个空心挂钩,这种画法稍微有点麻烦
  5. NG-ZORRO 表格多选框改为单选框 (angular框架)
  6. java 自定义tostring_自定义java toString方法
  7. C++编程进阶2(编译器在类内默认生成的函数讨论以及纯虚析构函数)
  8. opencv亚像素点检测
  9. 如何解一元一次方程视频_七年级数学教学视频-小邵课堂
  10. 分布式协议基础http协议