如何在没有函数的情况下拆分不同列中的字​​符串值

时间:2017-10-18 15:48:42

标签: sql sql-server tsql

我们将此查询称为具有2个值的函数。

Any

这就是结果:

Results

但是我们需要将“CampoValor”拆分为用Semicolon(;)

分隔的不同列

这样的事情:

Finish result

如果有可能,我们需要递归地解决这个问题。

1 个答案:

答案 0 :(得分:2)

这是一种内联方法,前提是您有固定或最大列数。

易于扩展或收缩......模式非常明确。

示例

Declare @YourTable table (ID int,SomeCol varchar(max))
Insert Into @YourTable values 
 (1,'Some;string;with;text')
,(2,'Another;string;with;some;more;text')

Select A.ID
      ,B.*
 From  @YourTable 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)')))
                      ,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(max)')))
                      ,Pos5 = ltrim(rtrim(xDim.value('/x[5]','varchar(max)')))
                      ,Pos6 = ltrim(rtrim(xDim.value('/x[6]','varchar(max)')))
                      ,Pos7 = ltrim(rtrim(xDim.value('/x[7]','varchar(max)')))
                      ,Pos8 = ltrim(rtrim(xDim.value('/x[8]','varchar(max)')))
                      ,Pos9 = ltrim(rtrim(xDim.value('/x[9]','varchar(max)')))
                From  (Select Cast('<x>' + replace((Select replace(A.SomeCol,';','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) as xDim) as X 
             ) B

<强>返回

enter image description here

  

编辑 - 功能

Select B.*
      ,Numero
 From  [dbo].[ObtenerDatosPropios] ('RE-00935898','Alvaro') 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)')))
                      ,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(max)')))
                      ,Pos5 = ltrim(rtrim(xDim.value('/x[5]','varchar(max)')))
                      ,Pos6 = ltrim(rtrim(xDim.value('/x[6]','varchar(max)')))
                      ,Pos7 = ltrim(rtrim(xDim.value('/x[7]','varchar(max)')))
                      ,Pos8 = ltrim(rtrim(xDim.value('/x[8]','varchar(max)')))
                      ,Pos9 = ltrim(rtrim(xDim.value('/x[9]','varchar(max)')))
                From  (Select Cast('<x>' + replace((Select replace(A.CampoValores,';','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) as xDim) as X 
             ) B
  

编辑2 - 动态

未经测试,但这应该有效。我们基本上是在动态SQL中做一些动态SQL。

Declare @SQL varchar(max) = '
Select A.Numero 
      ,Col = ''Pos''+cast(RetSeq as varchar(25))
      ,B.*
 Into  #Temp
 From  [dbo].[ObtenerDatosPropios] ('''+@P1+''','''+@P2+''') A
 Cross Apply (
                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(A.CampoValores,'';'',''§§Split§§'') as [*] For XML Path('''')),''§§Split§§'',''</x><x>'')+''</x>'' as xml).query(''.'')) as A 
                Cross Apply x.nodes(''x'') AS B(i)
             ) B

Declare @SQL varchar(max) 
Set @SQL =   Stuff((Select Distinct '',''+quotename(Col) From #Temp Order By 1 For XML Path('''')),1,1,'''')
Set @SQL = ''
Select ''+@SQL+'',Numero
 From  (Select Col,RetVal,Numero From #Temp) A
 Pivot (max([RetVal]) For [Col] in ('' + @SQL + '') ) p''
Exec(@SQL)
'
--Print @SQL
Exec(@SQL)