SQL实现多行合并一行
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一次性搞定,
而且扩充性很好,没有列的限制。
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的结果,即为所要求的数据行
来自: http://hi.baidu.com/hssfree/blog/item/dc9cdcb7521f09ff31add183.html
SQL合并行数据
SQL SERVER:在SQL中分类合并数据行
--1. 创建表,添加测试数据
CREATE TABLE test(code varchar(50), varchar(10))
INSERT test SELECT '001', 'aa'
UNION ALL SELECT '001', 'bb'
UNION ALL SELECT '002', 'aaa'
UNION ALL SELECT '002', 'bbb'
UNION ALL SELECT '002', 'ccc'
--SELECT * FROM test
code values
----------- ----------
001 aa
001 bb
002 aaa
002 bbb
002 ccc
(5 row(s) affected)
--2 在SQL2000只能用自定义函数实现
----2.1 创建合并函数fn_strSum,根据code合并values值
GO
CREATE FUNCTION dbo.fn_Sum(@code varchar(50))
RETURNS varchar(8000)
AS
BEGIN
DECLARE @values varchar(8000)
SET @values = ''
SELECT @values = @values + ',' + values FROM test WHERE code=@code
RETURN STUFF(@values, 1, 1, '')
END
GO
-- 调用函数
SELECT code, data = dbo.fn_Sum(code) FROM test GROUP BY code
DROP FUNCTION dbo.fn_Sum
----2.2 创建合并函数fnSum,根据code合并values值
GO
CREATE FUNCTION dbo.fnSum(@code varchar(50))
RETURNS varchar(8000)
AS
BEGIN
DECLARE @values varchar(8000)
SELECT @values = Isnull(@values + ',', '') + values FROM test WHERE code=@code
RETURN @values
END
GO
-- 调用函数
SELECT> DROP FUNCTION dbo.fnSum
--3 在SQL2005中的新解法
----3.1 使用XML
SELECT code, data=STUFF((SELECT ','+ FROM test t WHERE code=t1.code FOR XML PATH('')), 1, 1, '')
FROM test t1
GROUP BY code
--4 删除测试表test
drop table test
/**//*
code data
----------- --------------------
001 aa,bb
002 aaa,bbb,ccc
(2 row(s) affected)
页:
[1]