【问题标题】:Get a count of ranged and comma separated items in a string in SQL获取 SQL 中字符串中范围和逗号分隔项的计数
【发布时间】:2012-05-01 21:03:38
【问题描述】:

在 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. 将该数字添加到第一个数字以获得总计数

我完全不知道从哪里开始。有什么想法吗?

【问题讨论】:

  • 对不起,我最初没有包括那个。现在添加它...SQL SERVER 2008 R2
  • 你能用 CLR 函数代替 T-SQL 吗?
  • 我不确定用户定义函数和 CLR 函数之间有什么区别。鉴于我知道的函数使用 T-SQL,我猜这是不同的东西。请详细说明。如果它们相同,那么,是的,我可以使用一个函数,但我仍然不知道如何通过函数执行它。
  • CLR 函数是 SQL Server 实例中的一个对象,该对象在 .NET 框架中创建的程序集中进行编程。基本上,您将在 C# 或 VB.NET 中编写您的方法,然后将程序集导入 SQL Server。然后数据库可以像使用任何其他用户定义的函数一样使用该函数。

标签: sql string count sql-server-2008-r2


【解决方案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

【讨论】:

  • 这正是我想要的,让我从那里开始构建。完美,谢谢!!
【解决方案2】:

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

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

对于完整的解决方案,您需要做一些更复杂的事情。很久以前,我下载了一个名为 split 的函数,它接受一个分隔字符串并返回组件,就好像它是一个表一样。事实上,看起来我是从这里捡来的。 . . T-SQL: Opposite to string concatenation - how to split string into multiple records.

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

【讨论】:

  • 要计算值本身,请使用:select len(str) - len(replace(str, ',', '') + 1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多