【问题标题】:Get negative or positive numbers from a string从字符串中获取负数或正数
【发布时间】:2019-12-07 02:46:22
【问题描述】:

我只想从字符串中查询数字。这仅适用于提取正整数值。显然它从负整数中取出了 - 。

例如,执行这两个会给出相同的输出 10,但我希望在第二种情况下为 -10。

DECLARE @column VARCHAR(20) = '10th'
SELECT SUBSTRING(@column, PATINDEX('%[0-9]%', @column), PATINDEX('%[0-9][^0-9]%', @column + 't') - PATINDEX('%[0-9]%', 
                    @column) + 1)  

DECLARE @column VARCHAR(20) = '-10th'
SELECT SUBSTRING(@column, PATINDEX('%[0-9]%', @column), PATINDEX('%[0-9][^0-9]%', @column + 't') - PATINDEX('%[0-9]%', 
                    @column) + 1)  

当我将开始部分设为 -ve 并将子字符串长度部分的 +1 替换为 +5 时,它会在预期时检索负值。但是,当值为正时,它会留下部分字符串。

DECLARE @column VARCHAR(20) = '-10th'
SELECT SUBSTRING(@column, - PATINDEX('%[0-9]%', @column), PATINDEX('%[0-9][^0-9]%', @column + 't') - PATINDEX('%[0-9]%', 
                    @column) + 5)  

DECLARE @column VARCHAR(20) = '-10th'
SELECT SUBSTRING(@column, PATINDEX('%[0-9]%', @column), PATINDEX('%[0-9][^0-9]%', @column + 't') - PATINDEX('%[0-9]%', 
                    @column) + 5)  

我可以应用 CASE 语句来进行交互查询,例如:

DECLARE @column VARCHAR(20) = '10th'
SELECT CASE WHEN @column like '%-%' THEN 
 SUBSTRING(@column, - PATINDEX('%[0-9]%', @column), PATINDEX('%[0-9][^0-9]%', @column + 't') - PATINDEX('%[0-9]%', 
                    @column) + 5)  
ELSE SUBSTRING(@column, PATINDEX('%[0-9]%', @column), PATINDEX('%[0-9][^0-9]%', @column + 't') - PATINDEX('%[0-9]%', 
                    @column) + 1)  END 

但我想知道是否有一个简单的解决方法。

有人可以帮忙吗?

【问题讨论】:

    标签: sql sql-server select substring


    【解决方案1】:

    如果它总是以两个字母结尾,例如thnd,那么您可以使用leftlen

    DECLARE @column VARCHAR(20) = '-10th'
    
    DECLARE @column VARCHAR(20) = '10th'
    select left(@column,len(@column) - 2)
    

    否则,您可以从第二个数字开始查找第一个非数字。这将解释任何范围的数字,以及它们之后的任何数字。

    declare @table table (mycolumn varchar(64))
    insert into @table
    values
    ('10th'),
    ('-10th'),
    ('2nd'),
    ('-2nd'),
    ('104234thdsfasdf'),
    ('-104234thdsfasdf')
    select 
        substring(mycolumn,1,patindex('%[^0-9]%',right(mycolumn,len(mycolumn) -1)))
    from @table
    

    【讨论】:

      【解决方案2】:

      试试这个

      substring(@column, patindex('%[0-9-]%', @column), patindex('%[0-9-][^0-9]%', @column) - patindex('%[0-9-]%', @column) + 1)
      

      【讨论】:

        【解决方案3】:

        这行得通吗?

        PATINDEX('%[^-,^0-9%',@column)
        

        这应该包括任何负数

        【讨论】:

        • 这只是检索 0。你能写完整行吗?谢谢。
        【解决方案4】:

        这可能值得一试。 ISNULL/NULLIF 组合处理没有字母的行。以 0 为起点的 SUBSTRING 可防止负长度错误。

        SELECT SomeValue, ISNULL( NULLIF( SUBSTRING( SomeValue, 0, PATINDEX('%[^0-9-]%', SomeValue)),''), SomeValue)
        FROM (VALUES('10th'),('-10th'),
                    ('10'),('-10'),
                    ('1st'),('-1st'),
                    ('1'),('-1'),
                    ('108th'), ('-108th'), 
                    ('108'), ('-108'))x(SomeValue);
        

        【讨论】:

        • 加上 NULLIF 的好方法
        • 谢谢。这是我不久前从 Jeff Moden 和他对 DelimitedSplit8K 的​​测试中学到的技巧。我意识到我的代码与您的非常相似,但我发誓我没有复制任何东西。我们只是想法相同。
        • 即使你这样做了,你也改进了它,因此我的 +1
        猜你喜欢
        • 2021-03-24
        • 2019-02-01
        • 1970-01-01
        • 2015-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-09
        相关资源
        最近更新 更多