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 数据库实验课第五周——常用查询条件
Apr 05 SQL Server
SQLServer2008提示评估期已过解决方案
Apr 12 SQL Server
SQL Server代理:理解SQL代理错误日志处理方法
Jun 30 SQL Server
sql通过日期判断年龄函数的示例代码
Jul 16 SQL Server
万能密码的SQL注入漏洞其PHP环境搭建及防御手段
Sep 04 SQL Server
SQL Server中常用截取字符串函数介绍
Mar 16 SQL Server
如何使用SQL Server语句创建表
Apr 12 SQL Server
一次SQL查询优化原理分析(900W+数据从17s到300ms)
Jun 10 SQL Server
SQL中的连接查询详解
Jun 21 SQL Server
在SQL Server中使用 Try Catch 处理异常的示例详解
Jul 15 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
CURL的学习和应用(附多线程实现)
2013/06/03 PHP
php从字符串创建函数的方法
2015/03/16 PHP
Yii2单元测试用法示例
2016/11/12 PHP
PHP处理Ajax请求与Ajax跨域问题
2017/02/13 PHP
在IE上直接编辑网页内容的js代码(IE地址栏js)
2009/04/27 Javascript
JavaScript 学习笔记(四)
2009/12/31 Javascript
javascript 学习笔记(一)DOM基本操作
2011/04/08 Javascript
javascript操作table(insertRow,deleteRow,insertCell,deleteCell方法详解)
2013/12/16 Javascript
js实现俄罗斯方块小游戏分享
2014/01/31 Javascript
jquery修改网页背景颜色通过css方法实现
2014/06/06 Javascript
jquery 实现输入邮箱时自动补全下拉提示功能
2015/10/04 Javascript
chrome调试javascript详解
2015/10/21 Javascript
BACKBONE.JS 简单入门范例
2017/10/17 Javascript
基于Vue框架vux组件库实现上拉刷新功能
2017/11/28 Javascript
vue单页面打包文件大?首次加载慢?nginx带你飞,从7.5M到1.3M蜕变过程(推荐)
2018/01/16 Javascript
对mac下nodejs 更新到最新版本的最新方法(推荐)
2018/05/17 NodeJs
详解vue-cli3使用
2018/08/14 Javascript
JS中数据结构与算法---排序算法(Sort Algorithm)实例详解
2019/06/17 Javascript
layui时间控件选择时间范围的实现方法
2019/09/28 Javascript
Vue.js标签页组件使用方法详解
2019/10/19 Javascript
React学习之JSX与react事件实例分析
2020/01/06 Javascript
vue使用原生swiper代码实例
2020/02/05 Javascript
Python中字符串的处理技巧分享
2016/09/17 Python
Python中的连接符(+、+=)示例详解
2017/01/13 Python
Python3.7 新特性之dataclass装饰器
2019/05/27 Python
django基础学习之send_mail功能
2019/08/07 Python
python IDLE添加行号显示教程
2020/04/25 Python
Python+Appium实现自动化清理微信僵尸好友的方法
2021/02/04 Python
类和结构的区别
2012/08/15 面试题
党员民主生活会对照检查材料思想汇报
2014/09/28 职场文书
医院领导班子四风问题对照检查材料
2014/10/26 职场文书
个人先进事迹材料范文
2014/12/29 职场文书
教师求职简历自我评价
2015/03/10 职场文书
医院消毒隔离制度
2015/08/05 职场文书
教师法制教育培训学习心得体会
2016/01/14 职场文书
Pygame Draw绘图函数的具体使用
2021/11/17 Python