0

在 SQL SERVER 2008 R2 中,我需要获取包含在字符串中的项目计数,该字符串可以具有以下任何特征(由用户而不是系统控制):

  • 每个项目用逗号分隔
  • 由短划线分隔的第一个和最后一个项目汇总的顺序项目
  • 仅附加到破折号分隔范围中的第一项的非增量字符
  • 表示指定的非增量部分的多个字符
  • 以上结合

以下所有情况都是可能的:

  • R1,R2,R3,R4
  • R1-R4
  • R1-4
  • CP10-CP12
  • R1,R15-R19,RN5

如果它们都是逗号分隔的,我可以数逗号 +1,但这实际上不如其他选项常见。

计算最后一个选项的方法应该适用于所有选项。结果应该是 7

我预期的方法是:

  1. 没有破折号但用逗号分隔的项目=>获取计数
  2. 隔离破折号分隔的项目并删除非增量字符
  3. 从较大的数字中减去较小的数字并加1
  4. 将该数字添加到第一个数字以获得总计数

我完全坚持甚至从哪里开始。有任何想法吗?

4

2 回答 2

1

您可以使用一个技巧来计算逗号分隔列表中的逗号数:

select len(str) - len(replace(str, ',', '')

对于完整的解决方案,您需要做一些更复杂的事情。很久以前,我下载了一个名为 split 的函数,它接受一个分隔字符串并返回组件,就好像它是一个表一样。事实上,看起来我是从这里捡来的。. . T-SQL:与字符串连接相反 - 如何将字符串拆分为多条记录

因此,想法是拆分字符串,然后解析要计数的组件。如果没有连字符,则数“1”。如果有连字符,则需要解析字符串以获取计数。

于 2012-05-01T21:42:02.593 回答
1

这可以清理/优化,并且故意冗长,但应该让你开始。值得注意的是,最后一个 IF 内部的逻辑几乎与 WHILE 的逻辑相同,并且获取左/右元素数值的块重复了四次。

declare @input varchar(max)
set @input = 'R1,R15-R19,RN5-RN6'

select @input

declare @elements table
(
    Element varchar(10),
    [Count] int
)

declare @element varchar(10)
declare @index int
declare @count int
declare @left varchar(10)
declare @right varchar(10)
declare @position int

while (len(@input) > 0 and charindex(',', @input) > 0)
begin
    set @element = substring(@input, 0, charindex(',', @input))
    if (charindex('-', @element) > 0)
    begin
        set @index = charindex('-', @element)
        set @left = left(@element, @index - 1)
        set @right = substring(@element, @index + 1, len(@element) - len(@left))

        set @position = 0
        while (isnumeric(substring(@left, @position, 1)) = 0)
        begin
            set @position = @position + 1
        end
        set @left = substring(@left, @position, len(@left))

        set @position = 0
        while (isnumeric(substring(@right, @position, 1)) = 0)
        begin
            set @position = @position + 1
        end
        set @right = substring(@right, @position, len(@right))

        set @count = cast(@right as int) - cast(@left as int) + 1
    end
    else
    begin
        set @count = 1
    end
    insert into @elements select @element, @count
    set @input = replace(@input, @element + ',', '')
end

if (len(@input) > 0)
begin
    set @element = @input
    if (charindex('-', @element) > 0)
    begin
        set @index = charindex('-', @element)
        set @left = left(@element, @index - 1)
        set @right = substring(@element, @index + 1, len(@element) - len(@left))

        set @position = 0
        while (isnumeric(substring(@left, @position, 1)) = 0)
        begin
            set @position = @position + 1
        end
        set @left = substring(@left, @position, len(@left))

        set @position = 0
        while (isnumeric(substring(@right, @position, 1)) = 0)
        begin
            set @position = @position + 1
        end
        set @right = substring(@right, @position, len(@right))

        set @count = cast(@right as int) - cast(@left as int) + 1
    end
    else
    begin
        set @count = 1
    end
    insert into @elements select @element, @count
end

select * from @elements
select sum([Count]) from @elements

输出以下结果:

R1,R15-R19,RN5-RN6

R1      1
R15-R19 5
RN5-RN6 2

8
于 2012-05-01T22:13:07.010 回答