如何计算SQL varchar中某个子字符串的出现次数?

Ori*_*ian 137 t-sql sql-server

我有一个列格式为a,b,c,d的列.有没有办法在T-SQL中计算该值中逗号的数量?

cms*_*sjr 221

想到的第一种方法是通过用空字符串替换逗号并比较长度来间接地做到这一点

Declare @string varchar(1000)
Set @string = 'a,b,c,d'
select len(@string) - len(replace(@string, ',', ''))
Run Code Online (Sandbox Code Playgroud)

  • 这回答了文中所写的问题,但不是标题中所写的问题.要使它适用于多个角色,只需要在事物周围添加一个/ len(searchterm).在案例中发布答案对某人有用. (13认同)
  • 也许使用DATALENGTH代替LEN会更好,因为LEN返回修剪过的字符串的大小. (4认同)
  • 由于字符大小不明显,因此DATALENGTH()/ 2也很棘手。请查看stackoverflow.com/a/11080074/1094048,以获取获取字符串长度的简单而准确的方法。 (2认同)

And*_*ett 64

快速扩展cmsjr的答案,适用于更多字符的字符串.

CREATE FUNCTION dbo.CountOccurrencesOfString
(
    @searchString nvarchar(max),
    @searchTerm nvarchar(max)
)
RETURNS INT
AS
BEGIN
    return (LEN(@searchString)-LEN(REPLACE(@searchString,@searchTerm,'')))/LEN(@searchTerm)
END
Run Code Online (Sandbox Code Playgroud)

用法:

SELECT * FROM MyTable
where dbo.CountOccurrencesOfString(MyColumn, 'MyString') = 1
Run Code Online (Sandbox Code Playgroud)

  • 稍微改进的是使用DATALENGTH()/ 2而不是LEN().LEN将忽略任何尾随空格,因此`dbo.CountOccurancesOfString('blah,',',')`将返回2而不是1而``dbo.CountOccurancesOfString('hello world','')`将以0除以失败. (16认同)
  • 罗里的评论很有帮助.我发现我可以在Andrew的函数中用DATALENGTH替换LEN并获得所需的结果.数学运算的方式似乎没有必要除以2. (5认同)
  • `DATALENGTH()/2` 也很棘手,因为字符大小不明显。查看 http://stackoverflow.com/a/11080074/1094048 了解简单准确的方法。 (2认同)

Guf*_*ffa 22

您可以将字符串的长度与删除逗号的字符串进行比较:

len(value) - len(replace(value,',',''))
Run Code Online (Sandbox Code Playgroud)


bub*_*ing 6

@csmjr的回答在某些情况下有问题。

他的答案是这样做的:

Declare @string varchar(1000)
Set @string = 'a,b,c,d'
select len(@string) - len(replace(@string, ',', ''))
Run Code Online (Sandbox Code Playgroud)

这在大多数情况下都有效,但是,请尝试运行以下命令:

DECLARE @string VARCHAR(1000)
SET @string = 'a,b,c,d ,'
SELECT LEN(@string) - LEN(REPLACE(@string, ',', ''))
Run Code Online (Sandbox Code Playgroud)

由于某种原因,REPLACE会删除最后一个逗号,但也要删除它前面的空格(不确定原因)。当期望值为4时,结果返回值为5。这是另一种方法,即使在这种特殊情况下也可以使用:

DECLARE @string VARCHAR(1000)
SET @string = 'a,b,c,d ,'
SELECT LEN(REPLACE(@string, ',', '**')) - LEN(@string)
Run Code Online (Sandbox Code Playgroud)

请注意,您不需要使用星号。任何两个字符的替换都可以。这个想法是,对于要计算的字符的每个实例,将字符串延长一个字符,然后减去原始字符的长度。基本上,这是原始答案的相反方法,没有奇怪的修整副作用。

  • “由于某种原因,REPLACE删除了最后一个逗号,但也删除了它前面的空格(不确定原因)。” REPLACE并没有消除最后一个逗号和它前面的空格,实际上是LEN函数由于该空格而忽略了字符串结尾处的空格。 (5认同)

Rus*_*Fox 6

在@Andrew的解决方案的基础上,使用非过程表值函数和CROSS APPLY将获得更好的性能:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*  Usage:
    SELECT t.[YourColumn], c.StringCount
    FROM YourDatabase.dbo.YourTable t
        CROSS APPLY dbo.CountOccurrencesOfString('your search string',     t.[YourColumn]) c
*/
CREATE FUNCTION [dbo].[CountOccurrencesOfString]
(
    @searchTerm nvarchar(max),
    @searchString nvarchar(max)

)
RETURNS TABLE
AS
    RETURN 
    SELECT (DATALENGTH(@searchString)-DATALENGTH(REPLACE(@searchString,@searchTerm,'')))/NULLIF(DATALENGTH(@searchTerm), 0) AS StringCount
Run Code Online (Sandbox Code Playgroud)