随笔-100  评论-372  文章-1  trackbacks-36

ORACLE纯SQL实现多行合并一行

项目中遇到一个需求,需要将多行合并为一行。
表结构如下:
NAME                            Null           Type
------------------------   ---------   -----
N_SEC_CODE                 NOT NULL  CHAR(6)
C_RESEARCHER_CODE   NOT NULL  VARCHAR2(20)

此表保存了“股票”与“研究员”的对应关系数据,一般而言,对于同一只股票而言,可能有多个研究员
对其进行跟踪研究。所以目前遇到一个要求,需查询出每只股票和对应的研究员(研究员代码间,使用逗号分隔)。
例如有如下数据:
000297                                    chenpeng           
000297                                    liusu              
合并处理后需显示为:
000297                                    chenpeng,liusu

网上查了很多方法,但通常而言都是编写自定义多行文本合并函数,或者对支持的列数具有局限性。
最后在英文google中搜到如下比较巧的方法。不用在数据库中增加function,纯SQL一次性搞定,
而且扩充性很好,没有列的限制。

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的结果,即为所要求的数据行

方法很巧妙,值得学习。:-)

感谢网友@OctoberOne、@ericqliu的指点,在ORACLE10中可使用以下方法:
SELECT n_sec_code, wmsys.wm_concat (c_researcher_code) as result
FROM m_researcher_stock_rel
GROUP BY n_sec_code


posted on 2009-07-30 22:15 网际浪人 阅读(5398) 评论(11) 编辑 收藏

评论:
#1楼 2009-07-30 23:14 | 土农民      
路过
 回复 引用 查看   
#2楼 2009-07-30 23:38 | 简单就好      
复杂了。没必要。还不如直接在程序操作
 回复 引用 查看   
#3楼[楼主] 2009-07-31 00:45 | 网际浪人      
程序员有时还是想偷一下懒的,虽然代码里面是可以写。但如果SQL直接搞定这个结果,又何必代码里面再绕一圈呢。呵呵~~
 回复 引用 查看   
#4楼 2009-07-31 08:30 | OctoberOne      
wmsys.wm_concat
 回复 引用 查看   
#5楼 2009-07-31 08:37 | ericqliu      
Oracle 10g有提供wmsys.wm_concat。下面方法也许会简单点

SELECT n_sec_code, wmsys.wm_concat (DISTINCT c_researcher_code) as result
FROM m_researcher_stock_rel
GROUP BY n_sec_code

N_SEC_CODE result
-------------------- --------------
000297 chenpeng,liusu

 回复 引用 查看   
#6楼[楼主] 2009-07-31 08:55 | 网际浪人      
@OctoberOne
@ericqliu
谢谢提供

 回复 引用 查看   
#7楼 2009-07-31 10:24 | alanlau      
Oracle 8 怎么办?
 回复 引用 查看   
#8楼 2009-07-31 13:17 | 巫云      
我这sql server用游标写的。
 回复 引用 查看   
#9楼 2009-07-31 16:17 | shen126[未注册用户]
为什么我在这个版本上:Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 64bit)执行时会出现:
"wmsys.wm_concat invalid identifier"这样的错误提示?

 回复 引用   
#10楼[楼主] 2009-08-01 00:58 | 网际浪人      
@shen126
请确认你安装了 10g 的可选组件 “Workspace Manager”

 回复 引用 查看   
#11楼 2009-08-01 11:03 | WebClerk      
的确很巧妙啊
 回复 引用 查看   
 
【没有最完美的解决方案,只有最适合的解决方案——Karl He】
本博客文章版权声明:

浪人联系方式

  • Email:hekui168@163.com
  • MSN:wjlr008@hotmail.com
  • [通常情况建议使用邮件联系]




日历

昵称:网际浪人
园龄:6年1个月
粉丝:14
关注:0
<2009年7月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

搜索

 

常用链接

我的标签

随笔分类(104)

随笔档案(100)

技术网站

朋友的创业项目

同行

积分与排名

  • 积分 - 185370
  • 排名 - 457

最新评论

阅读排行榜

评论排行榜

推荐排行榜