你可以这样试试:
最简单的可能是古怪的更新,就像这里:
DECLARE @string VARCHAR(100)='abcdefghijklmnopqrstuvwxyz';
SELECT @string = STUFF(@string,3*A.pos,1,'.')
FROM (SELECT TOP(LEN(@string)/3) ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
FROM master..spt_values) A(pos);
SELECT @string;
Better/Cleaner/Prettier 是递归 CTE:
我们使用一个声明的表来拥有一些表格样本数据
DECLARE @tbl TABLE(ID INT IDENTITY, SomeString VARCHAR(200));
INSERT INTO @tbl VALUES('')
,('a')
,('ab')
,('abc')
,('abcd')
,('abcde')
,('abcdefghijklmnopqrstuvwxyz');
--查询
WITH recCTE AS
(
SELECT ID
,SomeString
,(LEN(SomeString)+1)/3 AS CountDots
,1 AS OccuranceOfDot
,SUBSTRING(SomeString,4,LEN(SomeString)) AS RestString
,CAST(LEFT(SomeString,2) AS VARCHAR(MAX)) AS Growing
FROM @tbl
UNION ALL
SELECT t.ID
,r.SomeString
,r.CountDots
,r.OccuranceOfDot+2
,SUBSTRING(RestString,4,LEN(RestString))
,CONCAT(Growing,'.',LEFT(r.RestString,2))
FROM @tbl t
INNER JOIN recCTE r ON t.ID=r.ID
WHERE r.OccuranceOfDot/2<r.CountDots-1
)
SELECT TOP 1 WITH TIES ID,Growing
FROM recCTE
ORDER BY ROW_NUMBER() OVER(PARTITION BY ID ORDER BY OccuranceOfDot DESC);
--结果
1
2 a
3 ab
4 ab
5 ab
6 ab.de
7 ab.de.gh.jk.mn.pq.st.vw.yz
简单的想法
- 我们使用递归 CTE 来遍历字符串
- 我们将所需部分与一个点一起添加
- 我们停止,当剩余长度短到继续时
-
ORDER BY ROW_NUMBER() OVER() 和TOP 1 WITH TIES 有点神奇。这将允许出现所有第一行(每个 ID 的第一行)。