更有效的方法来选择字符串中出现的次数

时间:2011-09-12 09:15:11

标签: sql sql-server tsql sql-server-2008

大家好我有以下脚本,这是完美的和花花公子并完成工作,但我不认为它是非常好或有效。只是想知道是否有更好,更有效的方法做同样的事情?工作是计算数字字符串中数字的出现次数,然后选择总数。例如,对于数字'014812000',预期结果应为6,因为我们有4 x 0次出现和2 x 1次出现。我们只关注超过1的事件。只是添加它正在用户定义的函数中使用。

DECLARE @Number nvarchar(50)
SET @Number = '014812000'

DECLARE @count0 int
DECLARE @count1 int
DECLARE @count2 int
DECLARE @count3 int
DECLARE @count4 int
DECLARE @count5 int
DECLARE @count6 int
DECLARE @count7 int
DECLARE @count8 int
DECLARE @count9 int

DECLARE @countTotal int
SET @countTotal = 0

SET @count0 = LEN(@Number) - LEN(REPLACE(@Number, '0', '')) 
SET @count1 = LEN(@Number) - LEN(REPLACE(@Number, '1', '')) 
SET @count2 = LEN(@Number) - LEN(REPLACE(@Number, '2', '')) 
SET @count3 = LEN(@Number) - LEN(REPLACE(@Number, '3', '')) 
SET @count4 = LEN(@Number) - LEN(REPLACE(@Number, '4', '')) 
SET @count5 = LEN(@Number) - LEN(REPLACE(@Number, '5', '')) 
SET @count6 = LEN(@Number) - LEN(REPLACE(@Number, '6', '')) 
SET @count7 = LEN(@Number) - LEN(REPLACE(@Number, '7', '')) 
SET @count8 = LEN(@Number) - LEN(REPLACE(@Number, '8', '')) 
SET @count9 = LEN(@Number) - LEN(REPLACE(@Number, '9', '')) 

IF @count0 > 1
    BEGIN
        SET @countTotal = @countTotal + @count0
    END
IF @count1 > 1
    BEGIN
        SET @countTotal = @countTotal + @count1
    END
IF @count2 > 1
    BEGIN
        SET @countTotal = @countTotal + @count2
    END
IF @count3 > 1
    BEGIN
        SET @countTotal = @countTotal + @count3
    END
IF @count4 > 1
    BEGIN
        SET @countTotal = @countTotal + @count4
    END
IF @count5 > 1
    BEGIN
        SET @countTotal = @countTotal + @count5
    END
IF @count6 > 1
    BEGIN
        SET @countTotal = @countTotal + @count6
    END
IF @count7 > 1
    BEGIN
        SET @countTotal = @countTotal + @count7
    END
IF @count8 > 1
    BEGIN
        SET @countTotal = @countTotal + @count8
    END
IF @count9 > 1
    BEGIN
        SET @countTotal = @countTotal + @count9
    END

SELECT @countTotal

3 个答案:

答案 0 :(得分:4)

您可以使用数字表将数字拆分为行。这里我使用master..spt_values。

select sum(C)
from (
       select count(*) as C
       from master..spt_values as N
       where N.type = 'P' and
             N.number between 1 and len(@Number)
       group by substring(@Number, N.Number, 1)
       having count(*) > 1
     ) as T      

答案 1 :(得分:2)

即使数字不是数字,也可以处理您的问题,它可以计算出现多于1个相同字符的任何字符出现。

它是为表格字符制作的。

declare @t table(number nvarchar(max))
insert @t values ('014812000')
insert @t values ('0148120001')
insert @t values ('0148120001aa')

;with a as
(
select number n, 0 i from @t
union all
select replace(n, cast(n as char(1)), ''), 
case when replace(n, cast(n as char(1)), '') = stuff(n,1,1,'') then i else 
i + cast(len(n) - len(replace(n, cast(n as char(1)), '')) as int)
end
from a
where n <> ''
)
select i from a where n = ''

如果您只想要一个特定的数字,那么您可以使用它:

declare @Number nvarchar(max) 
set @Number = '014812000'  

;with a as
(
select @number n, 0 i
union all
select replace(n, cast(n as char(1)), ''), 
case when replace(n, cast(n as char(1)), '') = stuff(n,1,1,'') then i else 
i + cast(len(n) - len(replace(n, cast(n as char(1)), '')) as int)
end
from a
where n <> ''
)
select i from a where n = ''

答案 2 :(得分:0)

看看this。它使用自定义功能。

FUNCTION dbo.com_CountString(@Input nVarChar(max), @SearchString nVarChar(1000))
RETURNS INT
BEGIN
DECLARE @Count INT, @Index INT, @InputLength INT, @SearchLength INT
DECLARE @SampleString INT

if @Input is null or @SearchString is null
    return 0

SET @Count = 0
SET @Index = 1
SET @InputLength  = LEN(@Input)
SET @SearchLength = LEN(@SearchString)

if @InputLength = 0 or @SearchLength = 0 or @SearchLength > @InputLength
    return 0

WHILE @Index <= @InputLength - @SearchLength + 1
BEGIN
    IF SUBSTRING(@Input, @Index, @SearchLength) = @SearchString
    BEGIN
        SET @Count = @Count + 1
        SET @Index = @Index + @SearchLength
    END
    ELSE
        SET @Index = @Index + 1
END

RETURN @Count
END