我只需要做类似的事情,但采取了不同的方法。我将相关字符串复制到了一个临时表中,我可以在其中添加列来跟踪每行上每个出现的索引。
在我的示例中,我在产品描述中寻找子字符串“-”(空格-破折号-空格),目的是最终将它们分开以显示为项目符号,我正在分析这样的数据查看通常有多少“子弹”产品。
我怀疑这比重复重写字符串值更有效,但我实际上并没有进行基准测试。
SELECT
ccp.ProductID, p.ProductDescription, descrlen=LEN(p.ProductDescription),
bulletcnt=0, indx=0, lastmatchat=0
INTO #DescrBullets
FROM Private.CompositeCatalogProduct AS ccp WITH(NOLOCK)
INNER JOIN Products.Product AS p WITH(NOLOCK) ON p.ProductId = ccp.ProductID
WHERE ccp.CompositeCatalogID=53
DECLARE @rows INT = 1
WHILE @rows>0
BEGIN
-- find the next occurrence on each row that's still in play
UPDATE #DescrBullets
SET lastmatchat = PATINDEX('% - %',RIGHT(ProductDescription,descrlen-indx))
WHERE indx<descrlen
-- anywhere that a match was found, increment my counter, and move my
-- index "cursor" past it
UPDATE #DescrBullets
SET bulletcnt = bulletcnt + 1,
indx = indx + lastmatchat + 2
WHERE lastmatchat>0
SET @rows = @@ROWCOUNT
-- for all the ones that didn't have a match, advance indx past the end
-- so we don't need to reprocess on next iterations
UPDATE #DescrBullets
SET indx=descrlen
WHERE lastmatchat=0
RAISERROR('processing, %d products still have bullets', 0, 1, @rows) WITH NOWAIT
END
SELECT db.bulletcnt, occurs=COUNT(*)
FROM #DescrBullets AS db
GROUP BY db.bulletcnt
ORDER BY 1