- 浏览: 89368 次
- 性别:
- 来自: 厦门
最新评论
-
zhengyong7232:
SELECT t.province,DECODE(landsc ...
列转行 -
meepo3927:
不是特么很懂
列转行
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_path
from (select deptno,
ename_path,
row_number() over(partition by deptno order by deptno, curr_level desc) ename_path_rank
from (
select empno,
deptno,
ename,
rank,
level as curr_level,
ltrim(sys_connect_by_path(ename, ','), ',') ename_path
from (select deptno,
ename,
empno,
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;
—————————————————————————————————————————————————
查询表中的一个字段,返回了多行,就把这么多行的数据都拼成一个字符串。
例: 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"
发表评论
-
oracle嵌套循环的执行计划优化
2013-06-15 23:28 0嵌套循环连接处理的 ... -
Oracle体系结构详解
2013-06-11 23:03 0Oracle体系结构就是围 ... -
ORACLE的隔离级别
2013-03-19 17:39 886隔离级别(isolation level) l ... -
Oracle 悲观锁和乐观锁
2013-03-19 17:30 1047一.丢失更新 所有多用户环境中存在丢失更新,丢失更新 ... -
Oracle异常
2012-10-16 21:48 4230Oracle异常处理异常处理是考验一个应用 程序 健壮性的最好 ... -
列转行
2012-07-12 11:51 1153oracle一个表或者视图中 ... -
oracle--多行转为一行的连接手段
2012-04-13 21:58 1130今天遇到将多行转为一行的一个操作,多谢oracle开发板的 w ... -
group by 多行变成一行-- (sum (case end case 也可以完成同样功能))
2012-04-13 21:52 3250select * from (select mtab.*, ... -
ORACLE实现多行合并一行的SQL写法
2012-04-12 16:55 1144项目中遇到一个需求, ... -
Oracle合并多行为多列[转]
2012-04-12 16:39 1409oracle 如何聚合多行函数 在BEA论坛上看一位&quo ...
相关推荐
总结来说,通过巧妙地运用Oracle的`CONNECT BY`和`SYS_CONNECT_BY_PATH`函数,我们可以实现多行数据到一行的合并,这对于报告展示和数据分析非常实用。不过要注意的是,这种方法在大数据量下可能会有性能问题,因为...
在Oracle数据库中,多行记录的合并通常是为了将相同字段的多行数据整合成一行,以便于数据分析或者简化展示。这种操作在报表制作、数据整理等场景中非常常见。本篇文章将详细介绍Oracle中实现多行记录合并的几种方法...
为了实现将Oracle数据库中某个字段的多行记录合并成一行记录的目标,可以采用编写自定义函数的方法。下面详细介绍该方法的具体步骤: #### 创建函数 `f_m_t` 首先,创建一个名为`f_m_t`的函数,该函数接受一个参数...
### Oracle多行合并为一行的方法 在Oracle数据库中,有时候我们需要将多行数据合并成一行进行展示或处理,尤其是在报表生成、数据展示等场景中。本文将详细介绍如何使用Oracle纯SQL语句实现这一功能,并通过具体...
本文实例讲述了oracle实现多行合并的方法。分享给大家供大家参考。具体分析如下: 在写sql时,经常会有将某列的字段合并起来,比如将某人名下每个月的工资列示,但是每个人只能占一行。 像这种场景,可能用行列转换...
在Oracle的PL/SQL编程中,函数是极其重要的组成部分,它们用于处理和操作数据。本篇文章将详细讲解PL/SQL中的单行函数和组函数。 首先,单行函数是针对单行数据进行操作的函数,它们可以应用于SQL查询的不同部分,...
Oracle 中实现行转列功能,并使用逗号进行隔开拼接,成为一条数据是指将多行数据合并成一行数据,并用逗号分隔每个字段的值。这种功能在实际应用中非常有用,例如在报表生成、数据分析和数据整合等场景中。 在 ...
在Oracle数据库中,将逗号分隔的字符串转换为多行是常见的数据处理需求,尤其在需要对每个分隔项进行单独操作时。这个过程通常涉及到字符串处理函数,如`REGEXP_SUBSTR`和`REPLACE`,以及层次查询结构`CONNECT BY`。...
在Oracle数据库中,合并多行记录的字符串是一个常见的需求,特别是在报表或数据分析中。这个问题涉及到字符串的连接和聚合,使得多个记录的某个字段值能够整合到一行。在Oracle中,虽然没有内置的聚合函数直接支持...
总结来说,这个示例展示了一种使用SQL自定义函数将多行数据合并为一行的方法,这在处理多值字段时非常有用,但需要注意性能和数据长度限制。在实际应用中,根据数据库系统的特性选择最适合的解决方案是至关重要的。
Oracle行转列是指在Oracle数据库中将行数据转换为列数据或将列数据转换为行数据的操作。这种操作在实际应用中非常有用,例如,在数据报表、数据分析和数据挖掘等领域都需要使用行转列操作。 1. 列转行 列转行是指...
- 进行行列转换的具体实现通常涉及多个步骤,包括找出关键字的属性个数,创建新的列,使用分析函数定位属性的位置,最后将多行数据合并为一列。具体的 SQL 语句可能会根据实际数据结构和需求有所不同,但主要思路是...
在SQL中,有时我们需要将具有相同属性的重复行数据合并成一行,并使用特定的分隔符,如逗号,来区分各个值。这种操作在处理报告或者数据分析时非常常见,可以减少数据的冗余,使结果更加简洁。本文将详细讲解如何在...
在Oracle中,有一个特殊的表`DUAL`,它只有一个名为`DUMMY`的列和一行数据。当你只需要执行一次计算,而不需要从实际表中获取数据时,可以使用`DUAL`表。例如,要获取当前日期,可以这样写: ```sql SELECT SYSDATE...
以上只是Oracle内建函数的一部分,实际中还有许多其他函数,如位运算函数、分析函数、游标函数等,它们极大地增强了SQL语言的功能,使得Oracle数据库能够处理各种复杂的数据操作。Oracle Built-in Functions.chm文件...
在实际业务场景中,有时我们需要将多行数据合并到一列,或者将一列数据分散到多行,以适应不同的分析需求。例如,一个销售报表可能需要按产品分类显示每个月的销售额,这时就需要将时间轴(月份)转换为列,而产品则...
这通常在每行数据中,使用group by和聚合函数max或min等来实现,将多个值合并为一个字符串。 5. 字符串转换成多列 字符串转换成多列是指将一个字符串拆分为多个列的过程。可以通过正则表达式来匹配特定模式的字符串...
OLAP函数用于复杂的分析操作,如LEAD和LAG函数获取当前行前后行的值,RANK、DENSE_RANK和ROW_NUMBER用于行号分配,FIRST_VALUE和LAST_VALUE获取分组内第一行或最后一行的值。 7. **查询优化**: 在实际查询中,...
这种方法利用了窗口函数`ROW_NUMBER()`来为每行分配一个序号,然后通过自连接找到相邻的行,最后使用`STRING_AGG`(这是一个模拟的函数,实际的Oracle中没有,但可以使用其他方法实现类似效果)进行合并。...
行转列可以用来将多行记录转换为一行记录,使用 MAX 函数可以实现此操作。 示例: ```sql SELECT MAX(DECODE(deptno, 10, '部门 10', 20, '部门 20', 30, '部门 30', '其他部门')) FROM emp; ``` Oracle 实践面试...