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 相关文章推荐
2021-4-5课程——SQL Server查询【3】
Apr 05 SQL Server
SQL 窗口函数实现高效分页查询的案例分析
May 21 SQL Server
解决sql server 数据库,sa用户被锁定的问题
Jun 11 SQL Server
SQL Server作业失败:无法确定所有者是否有服务器访问权限的解决方法
Jun 30 SQL Server
利用 SQL Server 过滤索引提高查询语句的性能分析
Jul 15 SQL Server
SQLServer之常用函数总结详解
Aug 30 SQL Server
SQL Server中常用截取字符串函数介绍
Mar 16 SQL Server
详解在SQLPlus中实现上下键翻查历史命令的功能
Mar 18 SQL Server
SQL CASE 表达式的具体使用
Mar 21 SQL Server
SQL Server删除表中的重复数据
May 25 SQL Server
SQL使用复合索引实现数据库查询的优化
May 25 SQL Server
SQL中的连接查询详解
Jun 21 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
一个SQL管理员的web接口
2006/10/09 PHP
php支持中文字符串分割的函数
2015/05/28 PHP
PHP实现的简单操作SQLite数据库类与用法示例
2017/06/19 PHP
PHP小白必须要知道的php基础知识(超实用)
2017/10/10 PHP
2017年最好用的9个php开发工具推荐(超好用)
2017/10/23 PHP
控制打印时页眉角的代码
2007/02/08 Javascript
奉献给JavaScript初学者的编写开发的七个细节
2011/01/11 Javascript
jQuery的live()方法对hover事件的处理示例
2014/02/27 Javascript
jQuery中:text选择器用法实例
2015/01/03 Javascript
js根据鼠标移动速度背景图片自动旋转的方法
2015/02/28 Javascript
JavaScript中的getTime()方法使用详解
2015/06/10 Javascript
jQuery实现带延迟效果的滑动菜单代码
2015/09/02 Javascript
node.js下LDAP查询实例分享
2015/09/30 Javascript
javascript实现动态统计图开发实例
2015/11/21 Javascript
详解Wondows下Node.js使用MongoDB的环境配置
2016/03/01 Javascript
jQuery Ajax前后端使用JSON进行交互示例
2017/03/17 Javascript
CentOS环境中MySQL修改root密码方法
2018/01/07 Javascript
vue axios 在页面切换时中断请求方法 ajax
2018/03/05 Javascript
JS使用setInterval实现的简单计时器功能示例
2018/04/19 Javascript
angularjs实现对表单输入改变的监控(ng-change和watch两种方式)
2018/08/29 Javascript
微信小程序实现蒙版弹窗效果
2018/11/01 Javascript
vue实现压缩图片预览并上传功能(promise封装)
2019/01/10 Javascript
对于Python编程中一些重用与缩减的建议
2015/04/14 Python
详解python 发送邮件实例代码
2016/12/22 Python
Python2.7下安装Scrapy框架步骤教程
2017/12/22 Python
解决Tensorflow使用pip安装后没有model目录的问题
2018/06/13 Python
python实现人脸签到系统
2020/04/13 Python
详解python如何引用包package
2020/06/07 Python
python中adb有什么功能
2020/06/07 Python
Python浮点型(float)运算结果不正确的解决方案
2020/09/22 Python
Kathmandu澳洲户外商店:新西兰户外运动品牌
2017/11/12 全球购物
教师的实习自我鉴定
2013/12/17 职场文书
教育专业自荐书范文
2013/12/17 职场文书
小学生学习感言
2014/03/10 职场文书
门市房租房协议书
2014/12/04 职场文书
酒店财务经理岗位职责
2015/04/08 职场文书