我如何在SQL Server中完成这个Excel函数?

我有大约30,000条logging,我需要分割Description字段,到目前为止,我似乎只能在Excel中实现这一点。 示例Description是:

 1USBCP 2RJ45C6 1DVI 1DP 3MD 3MLP HANDS 

以下是我的Excelfunction:

 =TRIM(MID(SUBSTITUTE($G309," ",REPT(" ",LEN($G309))),((COLUMNS($G309:G309)-1)*LEN($G309))+1,LEN($G309))) 

然后拖动这十个Excel列,并在每个空间拆分description字段。

我看到很多关于在SQL中分割string的问题,但是它们似乎只覆盖了一个空格,而不是多空格。

SQL服务器中没有简单的function来拆分string。 至less我不知道。 我通常使用一些我以前在互联网上find的技巧。 我修改它为你的例子。

诀窍是,首先我们试图找出我们需要多less列。 我们可以通过检查string中有多less个空string来实现。 最简单的方法是长度不超过空string的string长度。 之后,对于每个string,我们尝试按位置查找每个单词的开始和结束。 最后,我们把开始和结束位置的string简单地剪切,然后分配给coulmns。 详细信息在查询中。 玩的开心!

 CREATE TABLE test(id int, data varchar(100)) INSERT INTO test VALUES (1,'1USBCP 2RJ45C6 1DVI 1DP 3MD 3MLP HANDS') INSERT INTO test VALUES (2,'Shorter one') DECLARE @pivot varchar(8000) DECLARE @select varchar(8000) SELECT @pivot=coalesce(@pivot+',','')+'[col'+cast(number+1 as varchar(10))+']' FROM master..spt_values where type='p' and number<=(SELECT max(len(data)-len(replace(data,',',''))) FROM test) SELECT @select=' select p.* from ( select id,substring(data, start+2, endPos-Start-2) as token, ''col''+cast(row_number() over(partition by id order by start) as varchar(10)) as n from ( select id, data, n as start, charindex('','',data,n+2) endPos from (select number as n from master..spt_values where type=''p'') num cross join ( select id, '' '' + data +'' '' as data from test ) m where n < len(data)-1 and substring(odata,n+1,1) = '','') as data ) pvt Pivot ( max(token)for n in ('+@pivot+'))p' EXEC(@select) 

在这里你可以find在SQL小提琴的例子

我没有注意到你想摆脱多个空格。 要做到这一点,请创build一些function,准备您的数据:

 CREATE FUNCTION dbo.[fnRemoveExtraSpaces] (@Number AS varchar(1000)) Returns Varchar(1000) As Begin Declare @n int -- Length of counter Declare @old char(1) Set @n = 1 --Begin Loop of field value While @n <=Len (@Number) BEGIN If Substring(@Number, @n, 1) = ' ' AND @old = ' ' BEGIN Select @Number = Stuff( @Number , @n , 1 , '' ) END Else BEGIN SET @old = Substring(@Number, @n, 1) Set @n = @n + 1 END END Return @number END 

之后,使用删除多余空间的新版本。

 DECLARE @pivot varchar(8000) DECLARE @select varchar(8000) SELECT @pivot=coalesce(@pivot+',','')+'[col'+cast(number+1 as varchar(10))+']' FROM master..spt_values where type='p' and number<=(SELECT max(len(dbo.fnRemoveExtraSpaces(data))-len(replace(dbo.fnRemoveExtraSpaces(data),' ',''))) FROM test) SELECT @select=' select p.* from ( select id,substring(data, start+2, endPos-Start-2) as token, ''col''+cast(row_number() over(partition by id order by start) as varchar(10)) as n from ( select id, data, n as start, charindex('' '',data,n+2) endPos from (select number as n from master..spt_values where type=''p'') num cross join ( select id, '' '' + dbo.fnRemoveExtraSpaces(data) +'' '' as data from test ) m where n < len(data)-1 and substring(data,n+1,1) = '' '') as data ) pvt Pivot ( max(token)for n in ('+@pivot+'))p' EXEC(@select) 

我可能不理解你的问题,但是你在这个公式中所做的一切,在SQL中几乎可以完全相同。 我看到有人已经回答,但是在我看来,如果能做到这一点,怎么可能做到这一点呢? 我可能错了。 但是在这里。

 declare @test as varchar(100) set @test='abcd1234567' select right(@test,2) , left(@test,2) , len(@test) , case when len(@test)%2>0 then left(right(@test,round(len(@test)/2,0)+1),1) else left(right(@test,round(len(@test)/2,0)+1),2) end 

结果

  67 ab 11 2 

那么正确,左边,长度和中间都可以实现。

如果空格是“子string”分隔符,那么:我不记得做的真正的语法,而在SQLselect内部,我也没有实际上这样做,但我不明白为什么它不应该是可能的。 如果它不起作用,那么你需要一个临时表,如果这不起作用,你需要一个游标。 这个游标将是一个外部循环,一次只能获取和处理一个string。 或者你可以做更巧妙的事情。 我只是一个新手。

 declare @x varchar(1) declare @n integer declare @i integer declare @str varchar(100) -- this is your description. Fetch it and assign it. if in a cursor just use column-name set @x = null set @n = 0 set @i = 0 while n < len(@str) while NOT @x = " " begin set @x = left(right(@str,n),1) n = n+1 end --insert into or update @temptable blablabla here. 

使用我和n来定位子string,然后离开(右())。 或者你可以select它,但如果子string的数量很长,这是一个混乱的过程。 继续:

 set i = n set @str = right(@str, i) -- this includes the " ". left() it out at will. end 

现在,最后的评论,也许应该有第三个循环检查,如果你在最后的“子string”,因为我现在看到这个代码将抛出错误,当它到达最后。 或者在@str的末尾“添加”一个空的空间,这也是可行的。 但是我的时间到了。 至less这是一个build议。