我如何在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议。