我尝试将此字符串剪切为3或4个部分,最多只能包含40个字符。如果第40个字符在一个单词之间我必须找到最后一个空格然后剪切并放入地址1,然后从我停止我必须再次重新计算到40个字符,如果第40个字符仍然在一个单词的中间我必须返回并找到最后一个空格,依此类推,直到整个字符串被分割。 这是我目前的代码,我的想法。希望你能帮帮我。
declare @test varchar(150)
set @test = 'GTB INDUSTRIAL NETWORK DAVAO I GTB INDUSTRIAL NETWORK DAVAO I DOOR 10 2F SJRDC BLDG PHASE 1 INSULAR SUBD LANANG'
Select REVERSE(SUBSTRING(REVERSE(Substring(@test,0,40)),
CHARINDEX(' ',REVERSE(Substring(@test,0,40))),
len(Substring(@test,0,40)))),len(REVERSE(SUBSTRING(REVERSE(Substring(@test,0,40)),
CHARINDEX(' ',REVERSE(Substring(@test,0,40))),
len(Substring(@test,0,40)))))
Select Substring(@test,
Len(REVERSE(SUBSTRING(REVERSE(Substring(@test,0,40)),
CHARINDEX(' ',REVERSE(Substring(@test,0,40))),
len(Substring(@test,0,40)))
)),40),
len(Substring(@test,Len(REVERSE(SUBSTRING(REVERSE(Substring(@test,0,40)),
CHARINDEX(' ',REVERSE(Substring(@test,0,40))),
len(Substring(@test,0,40)))
)),40))
Select SUBSTRING(@test,((len(REVERSE(SUBSTRING(REVERSE(Substring(@test,0,40)),
CHARINDEX(' ',REVERSE(Substring(@test,0,40))),
len(Substring(@test,0,40)))))+2) +
len(REVERSE(SUBSTRING(REVERSE(Substring(@test,0,40)),
CHARINDEX(' ',REVERSE(Substring(@test,0,40))),
len(Substring(@test,0,40))))) +4 )
, 40), lEN(sUBSTRING(@test,((len(REVERSE(SUBSTRING(REVERSE(Substring(@test,0,40)),
CHARINDEX(' ',REVERSE(Substring(@test,0,40))),
len(Substring(@test,0,40)))))+2) +
len(REVERSE(SUBSTRING(REVERSE(Substring(@test,0,40)),
CHARINDEX(' ',REVERSE(Substring(@test,0,40))),
len(Substring(@test,0,40))))) +4 )
, 40))
答案 0 :(得分:0)
这是一个你可以使用的相当简单的算法(示意图,而不是实际运行的代码):
希望这有帮助。
答案 1 :(得分:0)
一种相当务实但相当快速的方法,适用于短字,省略任何高级复杂逻辑,是:
declare @test varchar(150)
set @test = 'GTB INDUSTRIAL NETWORK DAVAO I GTB INDUSTRIAL NETWORK DAVAO I DOOR 10 2F SJRDC BLDG PHASE 1 INSULAR SUBD LANANG';
WITH Splittable(Casted) AS
(
SELECT CAST('<x>' + REPLACE((SELECT @test AS [*] FOR XML PATH('')),' ','</x><x>') + '</x>' AS XML)
)
,Counted AS
(
SELECT part.value('.','nvarchar(max)') AS Part
,LEN(part.value('.','nvarchar(max)'))+1 AS LengthWithBlank
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowNr
FROM Splittable
CROSS APPLY Casted.nodes('/x') AS B(part)
)
,Grouped AS
(
SELECT *
,SUM(LEN(Part)) OVER(ORDER BY RowNr) /40 AS Grp
FROM Counted
)
SELECT g1.Grp
,(SELECT g2.Part + ' '
FROM Grouped AS g2
WHERE g2.Grp=g1.Grp
ORDER BY g2.RowNr
FOR XML PATH(''),TYPE
).value('.','nvarchar(max)')
FROM Grouped AS g1
GROUP BY g1.Grp;
这将首先将字符串拆分为其单词并将其返回并按每个部分的长度返回。
累积的SUM() OVER()
是整数除法 40,这会产生“群组”。最终的选择将返回每个组,结果如下:
Grp [splitted text]
0 GTB INDUSTRIAL NETWORK DAVAO I GTB INDUSTRIAL
1 NETWORK DAVAO I DOOR 10 2F SJRDC BLDG PHASE 1
2 INSULAR SUBD LANANG
这种方法不准确!(有些结果大于40),但很多短文都很好。您可以将CTE“Grouped”的结果继续使用另一种方法。
答案 2 :(得分:0)
这是一种Recursive CTE
方法。你的字符串不是那么长,所以你可以多次复制递归部分而不需要递归。
declare @test varchar(150)
set @test = 'GTB INDUSTRIAL NETWORK DAVAO I GTB INDUSTRIAL NETWORK DAVAO I DOOR 10 2F SJRDC BLDG PHASE 1 INSULAR SUBD LANANG'
;with cte as (
select @test txt, cast('' as varchar(200)) res
union all
select
cast(stuff(txt, 1, len(lres) + 1, '') as varchar(150)), cast(lres as varchar(200))c
from
cte
cross apply (select reverse(substring(txt, 1, 40)) rev_txt) ca2
cross apply (select reverse(right(rev_txt, len(rev_txt) - charindex(' ', rev_txt))) isspace) ca4
cross apply (select case when substring(txt, 41, 1) = ' ' then substring(txt, 1, 40) else isspace end lres) ca5
where
len(txt) > 0
)
select res from cte
where len(res) > 0
答案 3 :(得分:0)
我把它作为一个新答案,因为这是一个完全不同的方法,然后是我的第一个答案。这是确切的,但不是那么快:
declare @test varchar(150)
set @test = 'GTB INDUSTRIAL NETWORK DAVAO I GTB INDUSTRIAL NETWORK DAVAO I DOOR 10 2F SJRDC BLDG PHASE 1 INSULAR SUBD LANANG';
WITH recCTE AS
(
SELECT @test AS Original
,1 AS StartPos
,SUBSTRING(@test,1,1) AS SingleChar
,1 AS RunningPos
UNION ALL
SELECT Original
,CASE WHEN SUBSTRING(@test,RunningPos +1,1)=' ' AND CHARINDEX(' ',Original,RunningPos+2)-StartPos >=40 THEN RunningPos+2 ELSE StartPos END
,SUBSTRING(@test,RunningPos +1,1) AS SingleChar
,RunningPos +1
FROM recCTE
WHERE RunningPos<LEN(Original)
)
,GroupedCharacterList AS
(
SELECT *
FROM recCTE
)
SELECT LTRIM(RTRIM((
SELECT SingleChar AS [*]
FROM GroupedCharacterList AS gl2
WHERE gl2.StartPos=gl.StartPos
ORDER BY gl2.RunningPos
FOR XML PATH(''),TYPE
).value('.','nvarchar(max)')))
FROM GroupedCharacterList AS gl
GROUP BY StartPos
OPTION (MAXRECURSION 0);
递归CTE将逐个字符地读取。如果找到空白,它将查找字符串中的下一个空白并进行一些计算。如果下一个空白超过最大长度,则当前空白为新StartPos
,然后流程继续。
这最终被分组并重新协调