当前位置: 首页 > news >正文

04. 字符串合并与拆分写法小结

原文: 04. 字符串合并与拆分写法小结

一. 字符合并

if OBJECT_ID('ConcatStr') is not null
drop table ConcatStr
GO
create table ConcatStr
(
ID int,
Code varchar(10)
)
GO
insert into ConcatStr
select 1,'XXX' union all
select 1,'YYY' union all
select 2,'PPP' union all
select 2,'QQQ'

 要得到这样的结果:

IDCode
1XXX,YYY
2PPP,QQQ

1. 用游标

declare @t table(ID int, Code varchar(1000))
declare @id int
declare c cursor for 
select distinct ID from ConcatStr
open c
fetch next from c into @id
while @@fetch_status=0
begin
declare @str varchar(max)
set @str = ''
select @str = @str + ',' + Code from ConcatStr where ID = @id
insert into @t(ID, Code)
select @id,stuff(@str,1,1,'')
fetch next from c into @id
end
close c
deallocate c
select * from @t

 2. 用自定义函数

跟游标的方法类似,只是把逐个取的动作封装到函数里去了。
(1) 函数方法1

if OBJECT_ID('f_concat_str') is not null
drop function f_concat_str
GO
create function f_concat_str(@id int)
returns nvarchar(4000)
as
begin
declare @s nvarchar(4000)
set @s=''
select @s = @s+',' + Code from ConcatStr where ID = @id
return (stuff(@s,1,1,''))
--return (right(@s,len(@s)-1)) 
End

 (2) 函数方法2,就是把函数1再简化

if OBJECT_ID('f_concat_str') is not null
drop function f_concat_str
GO
create function f_concat_str(@id int)
returns nvarchar(4000)
as
begin
declare @s nvarchar(4000)
--set @s=''
--select @s = case when @s = '' then Code else @s + ',' + Code end
--from ConcatStr where ID = @id
select @s = isnull(@s + ',','') + Code from ConcatStr where ID = @id
return @s
end

 调用函数1或者函数2

--select ID,dbo.f_concat_str(ID) as Code
--from ConcatStr 
--group by ID
Select distinct ID, Code = dbo.f_concat_str(ID) 
from ConcatStr

 3. 利用静态的行列转换写法

给分组里的每行构造一个编号,行列转换后把列连接起来,编号多少个,取决于每个分组COUNT(1)的值。

SELECT ID,
       MAX(CASE WHEN num = 1 THEN Code ELSE '' END)
     + MAX(CASE WHEN num = 2 THEN ',' + Code ELSE '' END) AS Code
FROM (SELECT ID, Code,
      (SELECT COUNT(*)
         FROM dbo.ConcatStr AS t2
        WHERE t2.ID = t1.ID
          AND t2.Code <= t1.Code) AS num
FROM dbo.ConcatStr AS t1) AS t
GROUP BY ID;

 4. 用FOR XML子句

(1) FOR XML AUTO
SQL Server 2000就有这个子句,不过OUTER APPLY是SQL Server 2005的语法。通常这种写法效率上不会比用函数快。

SELECT * FROM(SELECT DISTINCT ID FROM ConcatStr)A OUTER APPLY(SELECT Code= STUFF(REPLACE(REPLACE((
SELECT Code FROM ConcatStr N WHERE ID = A.ID FOR XML AUTO), '<N Code="', ','), '"/>', ''), 1, 1, ''))N

 (2) FOR XML PATH

SQL Server 2005的新语法。

SELECT ID,
STUFF((SELECT ',' + Code
FROM dbo.ConcatStr AS t2
WHERE t2.ID = t1.ID
ORDER BY ID
FOR XML PATH('')), 1, 1, '') AS Code
FROM dbo.ConcatStr AS t1
GROUP BY ID;

 

二. 字符拆分

if not object_id('SplitStr') is null
drop table SplitStr
Go
create table SplitStr
(
Col1 int,
Col2 nvarchar(10)
)
insert SplitStr
select 1,N'a,b,c' union all
select 2,N'd,e' union all
select 3,N'f'
Go

 要得到这样的结果:

Col1Code
1a
1b
1c
2d
2e
3f

1. 使用数字辅助表

if object_id('Tempdb..#Num') is not null
drop table #Num
GO
select top 100 ID = Identity(int,1,1) into #Num 
--也可用ROW_NUMBER()来生成
from syscolumns a,syscolumns b
GO
Select a.Col1,Col2=substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID) 
from SplitStr a,#Num b
where charindex(',',','+a.Col2,b.ID)=b.ID 
--也可用substring(','+a.COl2,b.ID,1)=','

 2. 使用CTE

with t(Col1, p1, p2)
as
(
select Col1, charindex(',',','+col2), charindex(',',Col2+',') + 1 from SplitStr
union all
select s.Col1, t.p2, charindex(',', s.Col2+',', t.p2) + 1 
from SplitStr s join t on s.Col1 = t.Col1 where charindex(',', s.Col2+',', t.p2) > 0
)
--select * from t
select s.Col1, Col2 = substring(s.Col2+',', t.p1, t.p2-t.p1-1) 
from SplitStr s join t on s.Col1 = t.Col1 
order by s.Col1
option (maxrecursion 0)

 3. 使用XML

SELECT A.Col1, B.Code
FROM(SELECT Col1, Code = CONVERT(XML,'<root><v>' + REPLACE(Col2, ',', '</v><v>') + '</v></root>') FROM SplitStr) A
OUTER APPLY(SELECT Code = N.v.value('.', 'varchar(100)') FROM A.Code.nodes('/root/v') N(v)) B

  

相关文章:

  • Linux下的I/O
  • URLlib2 模拟浏览器header
  • 【原创】用SQL语句删除重复记录的方法总结
  • 软件定义的4-7层服务
  • 实现一个JavaScript验证的Asp.net Helper
  • HTML重构与网页常用工具
  • 国学应用大师翟鸿燊经典语录
  • shell---scp远程传输文件不需要手动输入密码
  • STP生成树协议
  • WDatePicker
  • OSPF笔记-2
  • 使用goldengate交付指定时间前的数据
  • 采购杀毒软件,你说话能算数么?
  • OpenStack 部署运维实战
  • 我的项目管理之路
  • [笔记] php常见简单功能及函数
  • 【css3】浏览器内核及其兼容性
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • 2019年如何成为全栈工程师?
  • FineReport中如何实现自动滚屏效果
  • httpie使用详解
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • Java多线程(4):使用线程池执行定时任务
  • mac修复ab及siege安装
  • PHP变量
  • Redis 懒删除(lazy free)简史
  • Sequelize 中文文档 v4 - Getting started - 入门
  • spring boot 整合mybatis 无法输出sql的问题
  • Swift 中的尾递归和蹦床
  • Web标准制定过程
  • Web设计流程优化:网页效果图设计新思路
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 汉诺塔算法
  • 首页查询功能的一次实现过程
  • 我的面试准备过程--容器(更新中)
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 新书推荐|Windows黑客编程技术详解
  • 阿里云重庆大学大数据训练营落地分享
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (接口自动化)Python3操作MySQL数据库
  • (九)信息融合方式简介
  • (三)c52学习之旅-点亮LED灯
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (转)winform之ListView
  • ***通过什么方式***网吧
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .NET CF命令行调试器MDbg入门(一)
  • .Net CF下精确的计时器
  • .NET CLR Hosting 简介