oracle sql分组合并
2015-08-15 13:34
691 查看
Sql代码 create table TABLE1 ( ID INTEGER, NAME VARCHAR2(10) ) create table TABLE2 ( ID INTEGER, ROLE VARCHAR2(10) ) insert into TABLE1 (ID, NAME) values (1, '张三'); insert into TABLE1 (ID, NAME) values (2, '李四'); commit; insert into TABLE2 (ID, ROLE) values (1, '查询'); insert into TABLE2 (ID, ROLE) values (1, '分析'); insert into TABLE2 (ID, ROLE) values (1, '决策'); insert into TABLE2 (ID, ROLE) values (2, '查询'); commit; create table TABLE1( ID INTEGER, NAME VARCHAR2(10))create table TABLE2( ID INTEGER, ROLE VARCHAR2(10))insert into TABLE1 (ID, NAME) values (1, '张三');insert into TABLE1 (ID, NAME) values (2, '李四');commit;insert into TABLE2 (ID, ROLE) values (1, '查询');insert into TABLE2 (ID, ROLE) values (1, '分析');insert into TABLE2 (ID, ROLE) values (1, '决策');insert into TABLE2 (ID, ROLE) values (2, '查询');commit; 要求输出结果: Sql代码 ID NAME ROLE 1 张三 查询,分析,决策 2 李四 查询 ID NAME ROLE1 张三 查询,分析,决策2 李四 查询 方法一、使用wmsys.wm_concat Sql代码 select table1.*,wmsys.wm_concat(role) from table1,table2 where table1.id=table2.id group by table1.id,table1.name 方法二、使用sys_connect_by_path Sql代码 select id, name, ltrim(max(sys_connect_by_path(role, ',')), ',') from (select row_number() over(partition by table1.id order by name) rn,table1.*, role from table1, table2 where table1.id = table2.id) start with rn = 1 connect by prior rn = rn - 1 and prior id = id group by id, name order by id select id, name, ltrim(max(sys_connect_by_path(role, ',')), ',') from (select row_number() over(partition by table1.id order by name) rn,table1.*, role from table1, table2 where table1.id = table2.id)start with rn = 1connect by prior rn = rn - 1 and prior id = idgroup by id, nameorder by id 例如有如下数据: 000297 chenpeng 000297 liusu 合并处理后需显示为: 000297 chenpeng,liusu 网上查了很多方法,但通常而言都是编写自定义多行文本合并函数,或者对支持的列数具有局限性。 最后在英文google中搜到如下比较巧的方法。不用在数据库中增加function,纯SQL一次性搞定, 而且扩充性很好,没有列的限制。 主要SQL如下: SELECT n_sec_code, TRANSLATE (LTRIM (text, '/'), '*/', '*,') researcherList FROM (SELECT ROW_NUMBER () OVER (PARTITION BY n_sec_code ORDER BY n_sec_code, lvl DESC) rn, n_sec_code, text FROM (SELECT n_sec_code, LEVEL lvl, SYS_CONNECT_BY_PATH (c_researcher_code,'/') text FROM (SELECT n_sec_code, c_researcher_code as c_researcher_code, ROW_NUMBER () OVER (PARTITION BY n_sec_code ORDER BY n_sec_code,c_researcher_code) x FROM m_researcher_stock_rel ORDER BY n_sec_code, c_researcher_code) a CONNECT BY n_sec_code = PRIOR n_sec_code AND x - 1 = PRIOR x)) WHERE rn = 1 ORDER BY n_sec_code; 预想的结果成功出现,多行数据成功汇总到一行,特此分享与大家。对于你自己的应用中,只需要把SQL中“n_sec_code” 换为你的用来汇总的列,“c_researcher_code”替换为需合并文本的列,“m_researcher_stock_rel”替换为你的表名,就是这么简单。 SQL分析: 1、利用 “ROW_NUMBER () OVER (PARTITION BY……” 为按“股票代码”汇总后的数据行添加组内序号 2、“SYS_CONNECT_BY_PATH” 按组内序号相邻关系,为每一层进行不同行的“研究员代码”叠加 3、再次利用“股票代码”进行组内分组,但按第二部中的层次排倒序,增加调整后等级 4、取所有调整后等级为1的结果,即为所要求的数据行 文章来自学IT网:http://www.xueit.com/html/2009-07/25_4207_00.html 方法三、使用自定义函数 Sql代码 ORACLE 分组多行合并一行 - winner - 宇宙的尽头的博客 create or replace function my_concat(mid in integer) return varchar2 --记住:参数和返回值里的数据类型都不用定义长度 is result varchar2(4000); --定义变量,记住Oracle中定义变量不需要 begin for temp_cursor in (select role from table2 where id=mid) loop --此处在游标FOR循环中使用查询 result :=result || temp_cursor.role || ','; --Oracle中字符连接使用||,而sql server中用+ end loop; result := rtrim(result,','); --去掉最后一个空格,还有Oracle中的赋值前面没有set return result; end; select table1.*,my_concat(table1.id) from table1,table2 where table1.id=table2.id group by table1.id,table1.name order by table1.id
相关文章推荐
- Oracle中查询前10条记录
- c# 连接oracle 读取数据
- 检索06 - Oracle MySql SqlSever之间的区别和优缺点
- oracle用户创建及权限设置
- 浅说两种输出Oracle字符文件的方法
- Oracle触发器
- 收藏:oracle中比较两表表结构差异和数据差异的方法
- oracle学习笔记(六)
- Oracle逻辑存储结构1—概述
- Oracle优化:大量数据插入或更新
- oracle表连接——处理连接过程中另外一张表没有相关数据不显示问题
- oracle的正则表达式
- Oracle常用函数
- ORACLE常用数值函数、转换函数、字符串函数
- oracle存储过程常用技巧
- Oracle 中union的用法
- oracle 学习笔记(五)
- oracle学习笔记(四)
- 为何要把你的SAP运行在Oracle数据库上?
- 甲骨文称 Google 毁掉了 Java 的市场