码迷,mamicode.com
首页 > 数据库 > 详细

SQL一字段内的字符串按照特定字符串转化为多行显示

时间:2019-01-18 19:58:15      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:逗号   cross   替换   rom   lin   src   9.png   max   数据表   

有如下数据表

技术分享图片

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

技术分享图片


一、利用XML解析方式

      先将该字段值统一替换为逗号分割,再将逗号分割替换转为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;

二、利用通用表达式CTE

;with CTE
as ( select *, row_number() over ( partition by id order by ( select 1 )) as SEQ from @table1 )

select   A.ID, substring(Col1, B.number, charindex(,, Col1 + ,, B.number) - B.number) as single_age
from     CTE A
         inner join master..spt_values B on charindex(,, , + Col1, B.number) = B.number
where    B.type = P
order by id, SEQ, B.number;

三、创建自定义函数

--1. 创建fn_Split函数. ( 切分字符串, 返回一个列名为id的表 )  
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 
    (
        --Example:  SELECT id FROM fn_Split(‘a,b,d,c‘,‘,‘)  
        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

使用函数

DECLARE @t TABLE (id INT,age NVARCHAR(MAX))
INSERT INTO @t VALUES(1,23|24|25|26|29)
INSERT INTO @t VALUES(1,33|aa|bb|cc|ss)
INSERT INTO @t VALUES(2,35|BB|CC|YY|RR)
 
SELECT a.id,b.id AS item 
FROM @t a CROSS APPLY dbo.fn_Split(a.age,|) AS b

SQL一字段内的字符串按照特定字符串转化为多行显示

标签:逗号   cross   替换   rom   lin   src   9.png   max   数据表   

原文地址:https://www.cnblogs.com/springsnow/p/10289104.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!