首页 > 解决方案 > 从字符串中获取负数或正数

问题描述

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

例如,执行这两个会给出相同的输出 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 

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

有人可以帮忙吗?

标签: sqlsql-serverselectsubstring

解决方案


这可能值得一试。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);

推荐阅读