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 相关文章推荐
SQLServer2008提示评估期已过解决方案
Apr 12 SQL Server
如何有效防止sql注入的方法
May 25 SQL Server
sql查询结果列拼接成逗号分隔的字符串方法
May 25 SQL Server
sql字段解析器的实现示例
Jun 23 SQL Server
数据库之SQL技巧整理案例
Jul 07 SQL Server
SqlServer数据库远程连接案例教程
Jul 15 SQL Server
SQLServer之常用函数总结详解
Aug 30 SQL Server
详解在SQLPlus中实现上下键翻查历史命令的功能
Mar 18 SQL Server
SQLServer RANK() 排名函数的使用
Mar 23 SQL Server
sqlserver连接错误之SQL评估期已过的问题解决
Mar 23 SQL Server
使用MybatisPlus打印sql语句
Apr 22 SQL Server
SQL SERVER中的流程控制语句
May 25 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
一个比较不错的PHP日历类分享
2014/11/18 PHP
php为字符串前后添加指定数量字符的方法
2015/05/04 PHP
浅析php静态方法与非静态方法的用法区别
2016/05/17 PHP
ThinkPHP 3.2.3实现加减乘除图片验证码
2018/12/05 PHP
jQuery asp.net 用json格式返回自定义对象
2010/04/07 Javascript
Javascript对象中关于setTimeout和setInterval的this介绍
2012/07/21 Javascript
键盘KeyCode值列表汇总
2013/11/26 Javascript
浅谈javascript六种数据类型以及特殊注意点
2013/12/20 Javascript
JavaScript用Number方法实现string转int
2014/05/13 Javascript
基于jquery的手风琴图片展示效果实现方法
2014/12/16 Javascript
jQuery如何解决IE输入框不能输入的问题
2016/10/08 Javascript
微信小程序 跳转方式总结
2017/04/20 Javascript
Node.js如何使用Diffie-Hellman密钥交换算法详解
2017/09/05 Javascript
微信小程序request请求后台接口php的实例详解
2017/09/20 Javascript
angular.js4使用 RxJS 处理多个 Http 请求
2017/09/23 Javascript
聊聊鉴权那些事(推荐)
2019/08/22 Javascript
微信小程序实现多选框全选与反全选及购物车中删除选中的商品功能
2019/12/17 Javascript
Angular如何由模板生成DOM树的方法
2019/12/23 Javascript
JavaScript实现公告栏上下滚动效果
2020/03/13 Javascript
[02:36]DOTA2混沌骑士 英雄基础教程
2013/11/26 DOTA
Django实战之用户认证(用户登录与注销)
2018/07/16 Python
python使用装饰器作日志处理的方法
2019/07/11 Python
python使用minimax算法实现五子棋
2019/07/29 Python
Keras loss函数剖析
2020/07/06 Python
python 自定义异常和主动抛出异常(raise)的操作
2020/12/11 Python
Python Selenium库的基本使用教程
2021/01/04 Python
乌克兰在线商店的价格比较:Price.ua
2019/07/26 全球购物
日语专业毕业生求职信
2013/12/04 职场文书
个人公开承诺书
2014/03/28 职场文书
房屋买卖协议书
2014/04/10 职场文书
道德演讲稿
2014/05/21 职场文书
经营场所证明范本
2015/06/19 职场文书
《狼牙山五壮士》读后感:宁死不屈,视死如归
2019/08/16 职场文书
Python爬虫基础讲解之请求
2021/05/13 Python
Nginx使用Lua模块实现WAF的原理解析
2021/09/04 Servers
《吸血鬼幸存者》新内容发布 追加多个全新模式
2022/04/07 其他游戏