Sql 查询以仅从字符串中获取数字

Sql 查询以仅从字符串中获取数字,sql,sql-server,Sql,Sql Server,我有这样的数据: string 1: 003Preliminary Examination Plan string 2: Coordination005 string 3: Balance1000sheet 我期望的结果是 string 1: 003 string 2: 005 string 3: 1000 我想在SQL中实现它。首先创建这个UDF CREATE FUNCTION dbo.udf_GetNumeric ( @strAlphaNumeric VARCHAR(256

我有这样的数据:

string 1: 003Preliminary Examination Plan   
string 2: Coordination005  
string 3: Balance1000sheet
我期望的结果是

string 1: 003
string 2: 005
string 3: 1000

我想在SQL中实现它。

首先创建这个
UDF

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
GO
现在使用
功能

SELECT dbo.udf_GetNumeric(column_name) 
from table_name

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
GO
我希望这解决了你的问题

请尝试:

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
GO
declare @var nvarchar(max)='Balance1000sheet'

SELECT LEFT(Val,PATINDEX('%[^0-9]%', Val+'a')-1) from(
    SELECT SUBSTRING(@var, PATINDEX('%[0-9]%', @var), LEN(@var)) Val
)x
试试这个-

查询:

DECLARE @temp TABLE
(
      string NVARCHAR(50)
)

INSERT INTO @temp (string)
VALUES 
    ('003Preliminary Examination Plan'),
    ('Coordination005'),
    ('Balance1000sheet')

SELECT LEFT(subsrt, PATINDEX('%[^0-9]%', subsrt + 't') - 1) 
FROM (
    SELECT subsrt = SUBSTRING(string, pos, LEN(string))
    FROM (
        SELECT string, pos = PATINDEX('%[0-9]%', string)
        FROM @temp
    ) d
) t
----------
003
005
1000
输出:

DECLARE @temp TABLE
(
      string NVARCHAR(50)
)

INSERT INTO @temp (string)
VALUES 
    ('003Preliminary Examination Plan'),
    ('Coordination005'),
    ('Balance1000sheet')

SELECT LEFT(subsrt, PATINDEX('%[^0-9]%', subsrt + 't') - 1) 
FROM (
    SELECT subsrt = SUBSTRING(string, pos, LEN(string))
    FROM (
        SELECT string, pos = PATINDEX('%[0-9]%', string)
        FROM @temp
    ) d
) t
----------
003
005
1000

通过前面的查询,我得到以下结果:

'aaaa1234bb3333'>>>>输出:1234

declare @StringAlphaNum varchar(255)
declare @Character varchar
declare @SizeStringAlfaNumerica int
declare @CountCharacter int

set @StringAlphaNum = 'AAAA1234BBBB3333'
set @SizeStringAlfaNumerica = len(@StringAlphaNum)
set @CountCharacter = 1

while isnumeric(@StringAlphaNum) = 0
begin
    while @CountCharacter < @SizeStringAlfaNumerica
        begin
            if substring(@StringAlphaNum,@CountCharacter,1) not like '[0-9]%'
            begin
                set @Character = substring(@StringAlphaNum,@CountCharacter,1)
                set @StringAlphaNum = replace(@StringAlphaNum, @Character, '')
            end
    set @CountCharacter = @CountCharacter + 1
    end
    set @CountCharacter = 0
end
select @StringAlphaNum
“-çã+0\aº1234'>>>输出:0

下面的代码返回所有数字字符:

第一次输出:12343333

第二次输出:01234

declare @StringAlphaNum varchar(255)
declare @Character varchar
declare @SizeStringAlfaNumerica int
declare @CountCharacter int

set @StringAlphaNum = 'AAAA1234BBBB3333'
set @SizeStringAlfaNumerica = len(@StringAlphaNum)
set @CountCharacter = 1

while isnumeric(@StringAlphaNum) = 0
begin
    while @CountCharacter < @SizeStringAlfaNumerica
        begin
            if substring(@StringAlphaNum,@CountCharacter,1) not like '[0-9]%'
            begin
                set @Character = substring(@StringAlphaNum,@CountCharacter,1)
                set @StringAlphaNum = replace(@StringAlphaNum, @Character, '')
            end
    set @CountCharacter = @CountCharacter + 1
    end
    set @CountCharacter = 0
end
select @StringAlphaNum
declare@StringAlphaNum varchar(255)
声明@Character varchar
声明@SizeStringAlfaNumerica int
声明@CountCharacter int
set@StringAlphaNum='aaaa1234bb3333'
设置@SizeStringAlfaNumerica=len(@StringAlphaNum)
设置@CountCharacter=1
而isnumeric(@StringAlphaNum)=0
开始
而@CountCharacter<@SizeStringAlfaNumerica
开始
如果子字符串(@StringAlphaNum,@CountCharacter,1)不象“[0-9]%”
开始
设置@Character=substring(@StringAlphaNum,@CountCharacter,1)
设置@StringAlphaNum=replace(@StringAlphaNum,@Character,'')
结束
设置@CountCharacter=@CountCharacter+1
结束
设置@CountCharacter=0
结束
选择@StringAlphaNum
查询:

DECLARE @temp TABLE
(
    string NVARCHAR(50)
)

INSERT INTO @temp (string)
VALUES 
    ('003Preliminary Examination Plan'),
    ('Coordination005'),
    ('Balance1000sheet')

SELECT SUBSTRING(string, PATINDEX('%[0-9]%', string), PATINDEX('%[0-9][^0-9]%', string + 't') - PATINDEX('%[0-9]%', 
                    string) + 1) AS Number
FROM @temp

我没有创建函数的权限,但有类似文本的权限

["blahblah012345679"]
需要从中间提取数字

注意:这假定数字分组在一起,而不是在字符串的开头和结尾

select substring(column_name,patindex('%[0-9]%', column_name),patindex('%[0-9][^0-9]%', column_name)-patindex('%[0-9]%', column_name)+1)
from table name

对@Epsicron的答案稍加修改

SELECT SUBSTRING(string, PATINDEX('%[0-9]%', string), PATINDEX('%[0-9][^0-9]%', string + 't') - PATINDEX('%[0-9]%', 
                    string) + 1) AS Number
FROM (values ('003Preliminary Examination Plan'),
    ('Coordination005'),
    ('Balance1000sheet')) as a(string)

不需要临时变量

虽然这是一个旧线程,这是谷歌搜索中的第一个线程,但我给出了一个与以前不同的答案。这将允许您传递字符串中要保留的内容的标准,不管该标准是什么。你可以把它放在一个函数中,如果你愿意,可以反复调用

declare @String VARCHAR(MAX) = '-123.  a    456-78(90)'
declare @MatchExpression VARCHAR(255) = '%[0-9]%'
declare @return varchar(max)

WHILE PatIndex(@MatchExpression, @String) > 0
    begin
    set @return = CONCAT(@return, SUBSTRING(@string,patindex(@matchexpression, @string),1))
    SET @String = Stuff(@String, PatIndex(@MatchExpression, @String), 1, '')
    end
select (@return)
在甲骨文中

您可以通过以下方式获得所需:

SUBSTR('ABCD1234EFGH',REGEXP_INSTR ('ABCD1234EFGH', '[[:digit:]]'),REGEXP_COUNT ('ABCD1234EFGH', '[[:digit:]]'))
示例查询:

SELECT SUBSTR('003Preliminary Examination Plan  ',REGEXP_INSTR ('003Preliminary Examination Plan  ', '[[:digit:]]'),REGEXP_COUNT ('003Preliminary Examination Plan  ', '[[:digit:]]')) SAMPLE1,
SUBSTR('Coordination005',REGEXP_INSTR ('Coordination005', '[[:digit:]]'),REGEXP_COUNT ('Coordination005', '[[:digit:]]')) SAMPLE2,
SUBSTR('Balance1000sheet',REGEXP_INSTR ('Balance1000sheet', '[[:digit:]]'),REGEXP_COUNT ('Balance1000sheet', '[[:digit:]]')) SAMPLE3 FROM DUAL

如果您使用的是Postgres,并且您有类似于“2000-一些示例文本”的数据,请尝试子字符串和位置组合,否则,如果在您的场景中没有分隔符,则需要编写正则表达式:

SUBSTRING(Column_name from 0 for POSITION('-' in column_name) - 1) as 
number_column_name

仅从字符串中获取数字可以在一行程序中完成。 试试这个:

SUBSTRING('your-string-here', PATINDEX('%[0-9]%', 'your-string-here'), LEN('your-string-here'))

NB:仅适用于字符串中的第一个int,例如:abc123vfg34返回123。

此自定义项适用于所有类型的字符串:

CREATE FUNCTION udf_getNumbersFromString (@string varchar(max))
RETURNS varchar(max)
AS
BEGIN
    WHILE  @String like '%[^0-9]%'
    SET    @String = REPLACE(@String, SUBSTRING(@String, PATINDEX('%[^0-9]%', @String), 1), '')
    RETURN @String
END

T-SQL函数从文本中读取所有整数,并返回指定索引处的整数,从左或右开始,同时使用起始搜索词(可选):

例如:

select dbo.udf_number_from text(N'Text text 10 text, 25 term', N'term',2,1);
返回10

该死的

此解决方案不同于所有早期解决方案,即:

  • 不需要创建函数
  • 不需要使用模式匹配
  • 不需要临时桌子
  • 此解决方案使用递归公共表表达式(CTE)
但首先,请注意,问题并没有指定这些字符串的存储位置。在下面的解决方案中,我创建了一个CTE,作为将这些字符串放入某种“源表”的一种快速而肮脏的方式

另外请注意-此解决方案使用了一个(CTE)-因此不要被这里使用的两个CTE弄糊涂。第一种方法只是使数据可用于解决方案,但解决此问题只需要第二种CTE。您可以修改代码,使第二个CTE查询成为您现有的表、视图等

最后-我的编码很冗长,试图使用列和CTE名称来解释发生了什么,您可能能够稍微简化这个解决方案。为了好玩,我添加了一些带有一些格式的伪电话号码(预期的和非典型的,视情况而定)

with SOURCE_TABLE as (
    select '003Preliminary Examination Plan' as numberString
    union all select 'Coordination005' as numberString
    union all select 'Balance1000sheet' as numberString
    union all select '1300 456 678' as numberString
    union all select '(012) 995 8322  ' as numberString
    union all select '073263 6122,' as numberString
),
FIRST_CHAR_PROCESSED as (
    select
        len(numberString) as currentStringLength,
        isNull(cast(try_cast(replace(left(numberString, 1),' ','z') as tinyint) as nvarchar),'') as firstCharAsNumeric,
        cast(isNull(cast(try_cast(nullIf(left(numberString, 1),'') as tinyint) as nvarchar),'') as nvarchar(4000)) as newString,
        cast(substring(numberString,2,len(numberString)) as nvarchar) as remainingString
    from SOURCE_TABLE
    union all
    select
        len(remainingString) as currentStringLength,
        cast(try_cast(replace(left(remainingString, 1),' ','z') as tinyint) as nvarchar) as firstCharAsNumeric,
        cast(isNull(newString,'') as nvarchar(3999)) + isNull(cast(try_cast(nullIf(left(remainingString, 1),'') as tinyint) as nvarchar(1)),'') as newString,
        substring(remainingString,2,len(remainingString)) as remainingString
    from FIRST_CHAR_PROCESSED fcp2
    where fcp2.currentStringLength > 1
)
select 
    newString
    ,* -- comment this out when required
from FIRST_CHAR_PROCESSED 
where currentStringLength = 1
这是怎么回事

基本上,在我们的CTE中,我们选择第一个字符,并使用
try_cast
()将其转换为
tinyint
(这是一个足够大的数据类型,可以容纳一位数字)。请注意,SQL Server中的类型转换规则表示空字符串(或空格)将解析为零,因此
nullif
被添加到强制空格和空字符串解析为null()(否则,每当源数据中遇到空格时,我们的结果将包含零字符)

CTE还返回第一个字符之后的所有内容,这将成为我们对CTE的递归调用的输入;换句话说:现在让我们处理下一个角色

最后,通过连接生成CTE中的字段
newString
(在第二个
SELECT
)。对于任何给定的列(包括列大小),使用两个
SELECT
语句之间的递归CTE。因为我们知道我们正在添加(最多)一个字符,所以我们正在将该字符转换为nvarchar(1),并将
新闻字符串转换为nvarchar(3999)。连接后,结果将是nvarchar(4000)-它与我们在第一个
选择
中执行的类型转换相匹配

如果运行此查询并排除
WHERE
子句,您将了解发生了什么,但行的顺序可能很奇怪。(您不一定会看到与单个输入值相关的所有行都分组在一起,但您应该仍然能够跟随)


希望这是一个有趣的选项,可以帮助一些需要严格基于表达式的解决方案的人。

首先找出数字的起始长度,然后反转字符串以再次找到第一个位置(这将给出数字从末尾开始的结束位置)。现在,若你们从两个数字中减去1,并从字符串的整个长度中减去它,你们将得到唯一的数字长度。现在去拿电话号码
--Add table to hold test data
CREATE TABLE dbo.NumTest (String VARCHAR(8000)) 

--Make an 8000 character string with mix of numbers and letters
DECLARE @Num VARCHAR(8000) = REPLICATE('12tf56se',800)

--Add this to the test table 500 times
DECLARE @n INT = 0
WHILE @n < 500
BEGIN
    INSERT INTO dbo.NumTest VALUES (@Num)
    SET @n = @n +1
END
SELECT dbo.GetNumbers(NumTest.String) AS Numbers
FROM dbo.NumTest -- Time to complete: 1 min 7s
SELECT dbo.udf_GetNumeric(NumTest.String)
FROM dbo.NumTest -- Time to complete: 3 mins 12s