SQL Server将Doc Breaks路径添加到单个分隔行

时间:2017-10-26 16:10:06

标签: sql sql-server

我经常在textpad和excel中使用正则表达式组合,但如果SQL中有编程方法,那将更加理想,我可以开始进行自动查询。

如果给出包含文档中断的图像路径的CSV文件:

Doc,Path,DocBreak
Doc01,C:\Image\01.tif,Y
Doc02,C:\Image\02.tif,
Doc03,C:\Image\03.tif,
Doc04,C:\Image\04.tif,Y
Doc05,C:\Image\05.tif,
Doc06,C:\Image\06.tif,Y

我正在寻找一种方法来获得这种输出,其中使用Y作为模式,将每个路径添加到多分隔字段,并为每个Y doc中断循环:

Doc,Path
Doc01,C:\Image\01.tif|C:\Image\02.tif|C:\Image\03.tif 
Doc04,C:\Image\04.tif|C:\Image\05.tif
Doc06,C:\Image\06.tif

是否有对此有用的SQL函数?

我正在使用Microsoft SQL Server MGMT工作室。谢谢。

2 个答案:

答案 0 :(得分:0)

如果您的服务器版本是SQL 2012或更高版本。你可以用这个,

DECLARE @Temp TABLE (Doc VARCHAR(20), Path VARCHAR(20),DocBreak VARCHAR(20))
INSERT INTO @Temp VALUES
('Doc01','C:\Image\01.tif','Y'),
('Doc02','C:\Image\02.tif',NULL),
('Doc03','C:\Image\03.tif',NULL),
('Doc04','C:\Image\04.tif','Y'),
('Doc05','C:\Image\05.tif',NULL),
('Doc06','C:\Image\06.tif','Y')

;WITH T AS (

SELECT *, GRP = SUM(CASE WHEN DocBreak ='Y' THEN 1 ELSE 0 END) OVER(ORDER BY Doc)
FROM @Temp
)
SELECT T1.Doc, STUFF(X.Path,1,1,'') Path FROM T T1
    OUTER APPLY (SELECT '|' + Path FROM T T2 WHERE T2.GRP = T1.GRP FOR XML PATH('') ) X (Path)
WHERE T1.DocBreak = 'Y'

结果:

Doc                  Path
-------------------- --------------------------------------------------------
Doc01                C:\Image\01.tif|C:\Image\02.tif|C:\Image\03.tif
Doc04                C:\Image\04.tif|C:\Image\05.tif
Doc06                C:\Image\06.tif

答案 1 :(得分:0)

如果要解析csv文件字符串

示例

Declare @csv varchar(max) = '
Doc,Path,DocBreak
Doc01,C:\Image\01.tif,Y
Doc02,C:\Image\02.tif,
Doc03,C:\Image\03.tif,
Doc04,C:\Image\04.tif,Y
Doc05,C:\Image\05.tif,
Doc06,C:\Image\06.tif,Y
'

;with cte as (
        Select A.RetSeq
              ,B.*
              ,Grp = sum(case when B.Pos3='Y' then 1 else 0 end) over (Order by A.RetSeq)
         From (
                Select RetSeq = Row_Number() over (Order By (Select null))
                      ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
                 From  (Select x = Cast('<x>' + replace((Select replace(@csv,char(13)+char(10),'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
                 Cross Apply x.nodes('x') AS B(i)
               ) A
         Cross Apply (
                        Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(max)')))
                              ,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(max)')))
                              ,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(max)')))
                        From  (Select Cast('<x>' + replace((Select replace(A.RetVal,',','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) as xDim) as A 
                     ) B
         Where Pos2 is not null and Pos3<>'DocBreak'
) 
Select Top 1 with ties
       Doc  = Pos1
      ,Path =Stuff((Select Distinct '|' +Pos2 From cte Where Grp=A.Grp For XML Path ('')),1,1,'') 
 From cte A
 Order By Row_Number() over (Partition by Grp Order by RetSeq)

<强>返回

Doc     Path
Doc01   C:\Image\01.tif|C:\Image\02.tif|C:\Image\03.tif
Doc04   C:\Image\04.tif|C:\Image\05.tif
Doc06   C:\Image\06.tif