主流数据库(SQL Server、Mysql、Oracle)通过sql实现多行数据合为一行 ...

打印 上一主题 下一主题

主题 803|帖子 803|积分 2409

主流数据库(SQL Server、Mysql、Oracle)通过sql实现多行数据合为一行

一、SQL Server

1、方法一:利用 STUFF 和 FOR XML PATH 进行多行合并成一行

(1)FOR XML PATH用法

FOR XML 是 SQL Server 提供的一种功能,允许您将查询效果转换为 XML 格式。PATH 模式则是其中一种机动的方式来构造自定义的XML结构。
1、基本字符勾通接: 当您想从单列中提取所有行的数据并连接成一个字符串列表时,可以利用 FOR XML PATH('')。
例如,假设有一个包含开发任务名称的 rwmc 列:
  1. SELECT
  2. rwmc + ','
  3. FROM table_name
  4. FOR XML PATH('')
复制代码
这段sql实验的效果将会返回一个XML字符串,其中每个任务名称后面跟着逗号,所闻名称连接在一起。如下:

2、指定元素标签: 若要将每个值包装在特定的XML元素内,您可以指定元素名称:
  1. SELECT
  2. rwmc as 'rwmcName'
  3. FROM table_name
  4. FOR XML PATH('rwmc')
复制代码
这将返回每个部分名称都在 <rwmcName> 元素内的XML结构。

3、创建嵌套结构: 若要创建更复杂的嵌套结构,可以结合 AS 关键字和 XPath 表达式:
  1. SELECT zyap,
  2.         (
  3.                 SELECT
  4.         rwmc
  5.         FROM table_name as d
  6.         FOR XML PATH('rwmc'),TYPE
  7.         )
  8. FROM table_name AS e
  9. FOR XML PATH('rwmcName'), ROOT('rwmcNames');
复制代码
上述查询会创建一个XML文档,其中包含一个名为 rwmcNames 的根元素,每个任务是一个 rwmcName 元素,zyap是一个属性,而每个r任务名称则嵌套在 rwmc 元素中。

4、消除尾部逗号: 如果在连接字符串时不需要末尾的分隔符(如逗号),通常会配合 STUFF() 和 SUBSTRING() 函数去除末了一个字符:
  1. SELECT STUFF(
  2.     (SELECT
  3. ','+rwmc
  4. FROM table_name
  5. WHERE mainid='03'
  6. FOR XML PATH('')
  7.     ), 1, 1, ''
  8. ) AS UnitsList;
复制代码

5、类型指示符


  • TYPE:返回的效果是XML数据类型,而不是字符串。
  • ELEMENTS:在PATH模式下强制所有标量值成为元素,而不是属性。
6、注意事项


  • 在 FOR XML PATH 中,空格和特别字符可能会被转义,如果需要原样输出文本,可以利用 TEXTPATH 或者设置 OPTION (QUOTE_IDENTIFIER OFF)。
  • 对于复杂层次的XML构建,或者需要完全控制XML结构的环境,可能需要结合 FOR XML EXPLICIT 利用。
(2)STUFF 用法

STUFF() 函数在 SQL Server 中主要用于对字符串操作,它能实现两个主要功能:

  • 删除字符串中的指定部分字符。
  • 插入新的字符序列到原始字符串中的指定位置。
以下是 STUFF() 函数的基本语法和用法:
  1. STUFF ( character_expression, start, length, add_string )
复制代码


  • character_expression: 这是要进行操作的原始字符串表达式。它可以是常量、变量或列名等。
  • start: 此参数表示从原始字符串的哪个位置开始删除字符。这个位置是从1开始计数的,即第一个字符的位置是1。
  • length: 指定要从 start 位置开始删除多少个字符。如果 length 为0,则不删除任何字符,仅插入 add_string。
  • add_string: 要插入到原始字符串中的新字符序列。在删除了 start 位置开始的 length 个字符后,这个字符串将被插入到指定位置。
  1. -- 示例1:删除并替换字符串中的部分内容
  2. DECLARE @originalString NVARCHAR(100) = 'Hello, World!';
  3. SELECT STUFF(@originalString, 7, 6, 'there');
  4. -- 结果:'Hello, there!'
  5. -- 此例中,从第7个位置开始删除了6个字符('World'),然后插入了'there'。
  6. -- 示例2:简单插入字符串
  7. DECLARE @anotherString VARCHAR(50) = 'SQLServer';
  8. SELECT STUFF(@anotherString, 7, 0, '2019 ');
  9. -- 结果:'SQL2019 Server'
  10. -- 此例中,没有删除任何字符,而是在第7个位置插入了'2019 '。
  11. -- 示例3:在具有多个记录的表中使用STUFF进行字符串拼接
  12. SELECT
  13.     ID,
  14.     STUFF((
  15.         SELECT ', ' + AnotherColumn
  16.         FROM YourTable AS YT2
  17.         WHERE YT1.ID = YT2.ID -- 确保只拼接同一ID下的记录
  18.         FOR XML PATH ('')
  19.     ), 1, 2, '') AS ConcatenatedValues
  20. FROM YourTable AS YT1
  21. GROUP BY ID;
  22. -- 这个例子中,STUFF与FOR XML PATH结合使用来拼接同一个ID下AnotherColumn列的所有值,以逗号+空格分隔,并移除了开头产生的额外的', '。
复制代码
(3)实现多行数据合并为一行

下面的sql可以直接利用
  1. SELECT STUFF(
  2.     (SELECT
  3. ','+column_name --这里替换为你的列名
  4. FROM your_table --这里替换为你的表名
  5. --这里添加你的查询条件
  6. FOR XML PATH('')
  7.     ), 1, 1, ''
  8. ) AS UnitsList;
复制代码
方法二:利用 STRING_AGG 函数

(1)STRING_AGG用法

STRING_AGG() 是一个在 SQL 中用于将多行数据合并成一列字符串的聚合函数,在 SQL Server 2017 及更高版本中,STRING_AGG() 函数的基本用法如下:
  1. STRING_AGG ( expression, separator )
复制代码


  • expression: 这是你想要连接起来的列或表达式的名称,或者是你要拼接的字符串字面量。
  • separator: 这是在连接相邻字符串之间的分隔符,可以是任何字符或字符串。
(2)实现多行数据合并为一行

例如,假设有一个包含开发任务名称的 rwmc 列,你想把所有任务名称连接起来,中间用逗号分隔:
  1. SELECT STRING_AGG(rwmc, ', ') AS rwmc
  2. FROM table_name
  3. GROUP BY SomeGroupingColumn; -- 如果需要按某个字段分组,如果你不需要分组,直接将所有行连接起来,则可以省略 GROUP BY 子句。
复制代码

二、Oracle

1、方法一:利用 LISTAGG 函数

LISTAGG 是Oracle从11g Release 2版本开始提供的内置聚合函数,它可以方便地将多行数据按指定分隔符串联起来:
  1. SELECT
  2. LISTAGG(value_column, ',') WITHIN GROUP (ORDER BY value_column) AS merged_column
  3. FROM your_table
复制代码

2、方法二:利用 WM_CONCAT 函数

WM_CONCAT 是Oracle的一个非标准函数,曾经在早期版本中非常盛行,但是在官方文档中并未正式支持。尽管如此,在某些旧版本的Oracle数据库中仍可找到这个函数并利用它来合并数据:
  1. SELECT
  2. WM_CONCAT(value_column) AS merged_column
  3. FROM your_table
复制代码

3、方法三:利用 XMLAGG 函数结合 XMLELEMENT 和 XMLSERIALIZE

当LISTAGG函数无法满意需求,比如合并后的字符串长度超过限定时,可以采用XML相干的函数来实现:
  1. SELECT
  2. RTRIM(XMLAGG(XMLELEMENT(e, value_column || ',')).EXTRACT('//text()'), ',') AS merged_column
  3. FROM your_table
复制代码

三、Mysql

1、方法一:利用 GROUP_CONCAT() 函数

GROUP_CONCAT() 是MySQL内置的聚合函数,可以用来将同一分组内的多个值合并成一个字符串,以指定的分隔符分隔各个值:
  1. SELECT
  2. GROUP_CONCAT(column2 SEPARATOR ',') AS merged_column
  3. FROM your_table
  4. --column1 是你想要分组的列,column2 是你想合并的列,而 , 是分隔符,你可以替换为你想要的任何字符。
复制代码
2、方法二: 子查询结合 GROUP_CONCAT() 函数

如果你需要更复杂的合并逻辑,可以结合子查询来利用 GROUP_CONCAT():
  1. SELECT t1.id,
  2.        (SELECT GROUP_CONCAT(column2 SEPARATOR ', ')
  3.         FROM your_table t2
  4.         WHERE t1.id = t2.id) AS merged_column
  5. FROM your_table t1;
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

耶耶耶耶耶

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表