??????峤 发表于 2018-10-23 12:02:18

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]
查看完整版本: SQL实现多行合并一行