T-SQL从字符串中提取十进制值

时间:2015-04-10 14:21:21

标签: sql tsql

好的,我要做的是从字符串中提取小数值。我的问题是字符串不统一。有些可能是6.9%或5.2mg / L,有些可能根本没有数值。我想要做的是返回字符串中的十进制(或整数)值,如果不存在则返回NULL。

我尝试过这个功能:

CREATE FUNCTION dbo.udf_GetNumeric
(@strAlphaNumeric VARCHAR(256))
RETURNS VARCHAR(256)
AS
BEGIN
DECLARE @intAlpha INT
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric)
BEGIN
WHILE @intAlpha > 0
BEGIN
SET @strAlphaNumeric = STUFF(@strAlphaNumeric, @intAlpha, 1, '' )
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric )
END
END
RETURN ISNULL(@strAlphaNumeric,0)
END

但是只返回没有小数位的数字。

4 个答案:

答案 0 :(得分:4)

您只需在.表达式中添加PATINDEX(点):

CREATE FUNCTION dbo.Udf_getnumeric (@strAlphaNumeric VARCHAR(256)) 
returns VARCHAR(256) 
AS 
  BEGIN 
      DECLARE @intAlpha INT 

      SET @intAlpha = Patindex('%[^0-9.]%', @strAlphaNumeric) 

      BEGIN 
          WHILE @intAlpha > 0 
            BEGIN 
                SET @strAlphaNumeric = Stuff(@strAlphaNumeric, @intAlpha, 1, '') 
                SET @intAlpha = Patindex('%[^0-9.]%', @strAlphaNumeric) 
            END 
      END 

      RETURN Isnull(@strAlphaNumeric, 0) 
  END

答案 1 :(得分:3)

另一种方法是删除字符串后面和字符串之前的字符。以下表达式执行此操作:

select val, 
       stuff(stuff(val+'x', patindex('%[0-9][^0-9.]%', val+'x') + 1, len(val), ''
                  ), 1, patindex('%[0-9]%', val) - 1, '')
from (values ('test123 xxx'), ('123.4'), ('123.4yyyyy'), ('tasdf 8.9'), ('asdb'), ('.2345')) as t(val);

内部stuff()删除号码后面的字符。 +'x'处理数字位于字符串末尾时发生的问题。第一部分处理数字前面的部分。

这假设字符串中只有一个数字。您可以使用where子句来检查:

where val not like '%[0-9]%[^0-9.]%[0-9]%'

答案 2 :(得分:2)

使用此功能,它还会返回十进制数字

import time
from tqdm import tqdm_notebook as tqdm

for i in tqdm(range(100))
    time.sleep(0.5)

SELECT dbo.udf_ExtractNumber('AD645.23DGD') Extracting Decimal number

Extracting Internet protocol number from string

答案 3 :(得分:0)

我认为我有最有效的方法,因为它不需要循环和最简单,因为我在一个短行中完成所有字符串操作。看看:

SELECT  string,
        CASE
            --If there's a number, then return it
            WHEN PATINDEX('%[0-9]%',string) != 0 
                --Pretty much find the first number and last number, then return that section(It's off by one so I so I add 1 at the end)
                THEN SUBSTRING(string,PATINDEX('%[0-9]%',string),DATALENGTH(string) - PATINDEX('%[0-9]%',REVERSE(string)) + 1)
            --If there are no numbers, return NULL
            ELSE NULL
        END return_int
FROM
(
    SELECT '123456789.3243421341% of mg/L blah blah blah whitespace    ' AS string
    UNION ALL
    SELECT 'No numbers here'
) A

结果:

string                                                      return_int
----------------------------------------------------------- -----------------------------------------------------------
123456789.3243421341% of mg/L blah blah blah whitespace     123456789.3243421341
No numbers here                                             NULL