SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串


Posted in SQL Server onMay 25, 2022

概述

  • STRING_AGG(合并):多行数据合并成一个字符串,以逗号隔开。
  • STRING_SPLIT(拆分):一个字符串,拆分成多行。

SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串

一、多行数据合并成一个字符串

1、通过 FOR xml path('') 合并字符串记录

根据name字段,合并code

declare  @table1  table (    id int ,code varchar(10) , name varchar(20) );
 
insert into @table1 ( id,code, name ) values ( 1, 'm1','a' ), ( 2,  'm2',null ), ( 3, 'm3', 'c' ), ( 4,  'm2','d' ), ( 5,  'm1','c' );

select * from @table1;

select name, files=stuff((select ','+convert(varchar, code)
                          from @table1 b
                          where a.name=b.name
                         for xml path('')), 1, 1, '')
from @table1 a
group by name;

结果:

SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串

2、MS SQL Server的2017新增了STRING_AGG()是一个聚合函数

它将由指定的分隔符分隔将字符串行连接成一个字符串。 它不会在结果字符串的末尾添加分隔符。

SELECT  name,   string_agg(code,';') files FROM @table1 GROUP BY name;

二、一个字符串拆分成多行

1、拆一列数据:

将如下从Excel复制的一栏数据,插入到表中行进显示(同时去掉回车换行符,空白和Tab符号):

1、利用XML解析方式(推荐)

declare @moulds varchar(4000);
set @moulds='55-480730-03,
55-487780-01,
,
 55-487780-02 ';
declare @table1 table(col1 nvarchar(4000));
declare @table2 table(col1 nvarchar(40),xmlval1 xml);
insert into @table1 values(replace(@moulds, char(13)+char(10), ''));
select * from @table1

insert into @table2  
select   rtrim(ltrim(replace(bs.v1, char(9), '') )),a.xmlval1
from (select convert(xml, '<n>'+replace(replace(col1, ',', ','), ',', '</n><n>')+'</n>') as xmlval1  
       from @table1) a
       cross apply(select k.n.value('.', 'nvarchar(80)') v1 from a.xmlval1.nodes('n') k(n) ) bs
where bs.v1 !='';

select * from @table2;

结果:

SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串

2、利用字符串拆解

declare @moulds varchar(4000);
set @moulds='55-480730-03,
55-487780-01,
,
 55-487780-02 ';
declare @table1 table(col1 nvarchar(4000));
declare @table2 table(col1 nvarchar(40), pos int);
insert into @table1 values(replace(@moulds, char(13)+char(10), ''));
select * from @table1;

insert into @table2
select rtrim(ltrim(replace(substring(A.col1, B.number, charindex(',', A.col1+',', B.number)-B.number) , char(9), '') )) as col2, B.number
from @table1 A
     inner join master..spt_values B
         on charindex(',', ','+A.col1, B.number)=B.number
where B.type='P';

select * from @table2;

结果:

SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串

2、拆多列数据:

有如下数据表

SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串

需求就是将Col1,Col2按照特定的字符串分割成多行

SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串

先将该字段值统一替换为逗号分割,再将逗号分割替换转为XML数据类型,再利用xml转为多个行

declare @table1 table
    (
        ID int ,
        Col1 nvarchar(50) ,
        Col2 nvarchar(50)
    );

insert into @table1 values ( 1, 'a,b,c', '诶,必,塞,地,伊' );
insert into @table1 values ( 2, 'w', N'三四,不知道咧' );


--方式一
select a.ID, a.Col1, a.Col2,  v1, v2
from   (   select ID, Col1, Col2, convert(xml, '<n>' + replace(replace(Col1, ',', ','), ',', '</n><n>') + '</n>') as xmlval1 ,
                                  convert(xml, '<n>' + replace(replace(Col2, ',', ','), ',', '</n><n>') + '</n>') as xmlval2
           from   @table1 ) a
       cross apply (   select k.n.value('.', 'nvarchar(80)') v1
                       from   a.xmlval1.nodes('n') k(n) ) bs
       cross apply (   select k.n.value('.', 'nvarchar(80)') v2
                       from   a.xmlval2.nodes('n') k(n) ) ns;

--方式二
select ID, t.Col1,t.Col2,  v1, v2
from   @table1 as t
       cross apply ( values (convert(xml, '<n>' + replace(replace(Col1, ',', ','), ',', '</n><n>')+ '</n>'), 
                             convert(xml, '<n>' + replace(replace(Col2, ',', ','), ',', '</n><n>')+ '</n>'))
                   ) a (xmlval1 , xmlval2 )
       cross apply (   select k.n.value('.', 'varchar(80)') as v1
                       from   a.xmlval1.nodes('n') k(n)) bs
       cross apply (   select k.n.value('.', 'varchar(80)') as v2
                       from   a.xmlval2.nodes('n') k(n) ) ns;

3、创建自定义拆分函数

函数功能:切分字符串, 返回一个列名为id的表

--1. 创建fn_Split函数
IF EXISTS(
       SELECT *
       FROM   dbo.sysobjects
       WHERE  id = OBJECT_ID('fn_Split')
              AND (TYPE = 'FN' OR TYPE = 'TF' OR TYPE = 'IF')
   )
    DROP FUNCTION fn_Split  
GO  
   
CREATE FUNCTION [dbo].[fn_Split]
(
    @str           VARCHAR(MAX),
    @separator     VARCHAR(10)
)
RETURNS TABLE
AS
    RETURN 
    (
        
        SELECT B.id
        FROM   (
                   (
                          --A 的作用只是生成 '<v>a</v><v>b</v><v>d</v><v>c</v>' 的XML格式的数据, 提供数据源 
                       SELECT [value] = CONVERT(XML, '<v>' + REPLACE(@str, @separator, '</v><v>') + '</v>')
                   ) A 
                   OUTER APPLY
                   (
                          --B 的作用是将A中的 XML 数据的值枚举出来转换成行
                       SELECT id = N.v.value('.', 'varchar(100)') FROM   A.[value].nodes('/v') N(v)
                   ) B
               )
    )
GO

使用函数 SELECT id FROM fn_Split('a,b,d,c',',')

declare @moulds varchar(4000);
set @moulds='55-480730-03,
55-487780-01,
,
 55-487780-02 ';
declare @table1 table(id INT,col1 nvarchar(MAX));

INSERT INTO @table1 VALUES(1,replace(@moulds, char(13)+char(10), ''))
INSERT INTO @table1 VALUES(2,replace(@moulds, char(13)+char(10), ''))
select * from @table1;

SELECT a.id,rtrim(ltrim(replace(b.id, char(10), '') )) AS item 
FROM @table1 a CROSS APPLY dbo.fn_Split(a.col1,',') AS b
where b.id !=''

4、SQL Server 2016新增了string_split函数

专门用来拆分字符串。

SELECT t.id,
       t.name,
       t.description,
       v.value
FROM test t
    CROSS APPLY STRING_SPLIT(t.description, ',')v;

到此这篇关于SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串的文章就介绍到这了。


Tags in this post...

SQL Server 相关文章推荐
Sql-Server数据库单表查询 4.3实验课
Apr 05 SQL Server
SqlServer: 如何更改表的文件组?(进而改变存储位置)
Apr 05 SQL Server
SQL Server2019数据库之简单子查询的具有方法
Apr 27 SQL Server
SQL Server中使用判断语句(IF ELSE/CASE WHEN )案例
Jul 07 SQL Server
SQL中的三种去重方法小结
Nov 01 SQL Server
SQLServer中exists和except用法介绍
Dec 04 SQL Server
SQL SERVER实现连接与合并查询
Feb 24 SQL Server
SQL Server查询某个字段在哪些表中存在
Mar 03 SQL Server
SQL Server中的游标介绍
May 20 SQL Server
SQL Server2019安装的详细步骤实战记录(亲测可用)
Jun 10 SQL Server
SQL bool盲注和时间盲注详解
Jul 23 SQL Server
SQL Server使用CROSS APPLY与OUTER APPLY实现连接查询
May 25 #SQL Server
SQL Server使用PIVOT与unPIVOT实现行列转换
May 25 #SQL Server
SQL SERVER中的流程控制语句
May 25 #SQL Server
SQL Server中搜索特定的对象
May 25 #SQL Server
SQL Server使用T-SQL语句批处理
May 20 #SQL Server
SQL Server 中的事务介绍
May 20 #SQL Server
SQL Server中锁的用法
May 20 #SQL Server
You might like
追求程序速度,而不是编程的速度
2008/04/23 PHP
php操作xml
2013/10/27 PHP
php中file_get_content 和curl以及fopen 效率分析
2014/09/19 PHP
PHP实现Soap通讯的方法
2014/11/03 PHP
PHP清除字符串中所有无用标签的方法
2014/12/01 PHP
Laravel框架实现的使用smtp发送邮件功能示例
2019/03/12 PHP
jValidate 基于jQuery的表单验证插件
2009/12/12 Javascript
jquery DIV撑大让滚动条滚到最底部代码
2013/06/06 Javascript
jquery 淡入淡出效果的简单实现
2014/02/07 Javascript
jquery数组过滤筛选方法grep()简介
2014/06/06 Javascript
javascript基本包装类型介绍
2015/04/10 Javascript
JavaScript实现表格点击排序的方法
2015/05/11 Javascript
vue项目中使用ueditor的实例讲解
2018/03/05 Javascript
移动端图片上传旋转、压缩问题的方法
2018/10/16 Javascript
详解iframe跨域的几种常用方法(小结)
2019/04/29 Javascript
JavaScript实现文件下载并重命名代码实例
2019/12/12 Javascript
[43:51]2018DOTA2亚洲邀请赛3月30日 小组赛B组 EG VS Secret
2018/03/31 DOTA
Python中使用PyHook监听鼠标和键盘事件实例
2014/07/18 Python
简单谈谈Python的pycurl模块
2018/04/07 Python
python中int与str互转方法
2018/07/02 Python
python 遍历目录(包括子目录)下所有文件的实例
2018/07/11 Python
Django之PopUp的具体实现方法
2019/08/31 Python
tensorflow实现tensor中满足某一条件的数值取出组成新的tensor
2020/01/04 Python
解决Pytorch 加载训练好的模型 遇到的error问题
2020/01/10 Python
wxpython自定义下拉列表框过程图解
2020/02/14 Python
Django-Scrapy生成后端json接口的方法示例
2020/10/06 Python
python 自动识别并连接串口的实现
2021/01/19 Python
泰国演唱会订票网站:StubHub泰国
2018/02/26 全球购物
台湾家适得:Homeget
2019/02/11 全球购物
时尚、社区、科技:SEVENSTORE
2019/04/26 全球购物
中专生自荐信
2013/10/12 职场文书
旅游安全协议书
2014/04/21 职场文书
党员群众路线剖析材料
2014/10/08 职场文书
国防教育标语
2014/10/08 职场文书
2014年乡镇纪委工作总结
2014/12/19 职场文书
小学班主任研修日志
2015/11/13 职场文书