【问题标题】:SQL take just the numeric values from a varcharSQL 仅从 varchar 中获取数值
【发布时间】:2012-07-05 04:38:26
【问题描述】:

假设我有如下几个字段:

abd738927
jaksm234234
hfk342
ndma0834
jon99322

类型:varchar。

如何仅从中获取数值来显示:

738927
234234
342
0834
99322

尝试过子字符串,但数据长度不同,并且由于无法转换而无法转换,有什么想法吗?

【问题讨论】:

  • 是的,patindex,假设所有数字都分组在一起,就像你的例子一样,否则你可能需要一个函数。
  • 您必须在 SQL 中执行此操作还是允许查询后操作?如果是这样,那么我将使用正则表达式来提取要显示的数字;我粗略搜索了一下,没有发现任何可以在 SELECT 和 FROM 之间使用正则表达式的东西。
  • @SelectDistinct - 我的答案中缺少什么?您是否使用以下代码测试了已接受的帖子DECLARE @a VARCHAR(1212) = 'eded123wsws' SELECT SUBSTRING(@a, PATINDEX('%[0-9]%', @a), LEN(@a))

标签: sql sql-server sql-server-2008 tsql


【解决方案1】:

这是使用 PATINDEX 的示例:

select SUBSTRING(fieldName, PATINDEX('%[0-9]%', fieldName), LEN(fieldName))

这假设 (1) 字段将有一个数字,(2) 数字全部组合在一起,并且 (3) 数字后面没有任何后续字符。

【讨论】:

  • 如果字段没有数字怎么办?
  • @user990016 然后添加 where 子句以过滤掉这些记录,或者添加 case 语句以返回这些记录的默认值。所以:WHERE fieldName LIKE '%[0-9]%'CASE WHEN fieldName NOT LIKE '%[0-9]%' THEN 'DEFAULT_VALUE' ELSE SUBSTRING(fieldName, PATINDEX('%[0-9]%', fieldName), LEN(fieldName)) END
  • 如果字符串以数字开头,然后是字符,然后是数字怎么办?例如:“123abc$%10xyz9”。如何使用 select 语句获得“123109”的结果?
【解决方案2】:

只提取数字(不使用while循环)并检查每个字符是否为数字并提取它

   Declare @s varchar(100),@result varchar(100)
    set @s='as4khd0939sdf78' 
    set @result=''

    select
        @result=@result+
                case when number like '[0-9]' then number else '' end from 
        (
             select substring(@s,number,1) as number from 
            (
                select number from master..spt_values 
                where type='p' and number between 1 and len(@s)
            ) as t
        ) as t 
    select @result as only_numbers 

【讨论】:

    【解决方案3】:
    DECLARE @NonNumeric varchar(1000) = 'RGI000Testing1000'
    DECLARE @Index int  
    SET @Index = 0  
    while 1=1  
    begin  
        set @Index = patindex('%[^0-9]%',@NonNumeric)  
        if @Index <> 0  
        begin  
            SET @NonNumeric = replace(@NonNumeric,substring(@NonNumeric,@Index, 1), '')  
        end  
        else    
            break;   
    end     
    select @NonNumeric -- 0001000
    

    【讨论】:

      【解决方案4】:

      我认为您需要 VBA 的 Val() 函数。使用IsNumeric() 很容易完成

      create function Val 
      (
          @text nvarchar(40)
      ) 
      returns float
      as begin
          -- emulate vba's val() function
          declare @result float 
          declare @tmp varchar(40)
      
          set @tmp = @text
          while isnumeric(@tmp) = 0 and len(@tmp)>0 begin
              set @tmp=left(@tmp,len(@tmp)-1)
          end
          set @result = cast(@tmp as float)
      
          return @result
      end
      

      【讨论】:

        【解决方案5】:

        如果你不想创建一个函数,你可以这样:

        cast(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(
        replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(
        replace(replace(replace(replace(replace(replace(replace(replace(replace(YOUR_COLUMN
        ,'A',''),'B',''),'C',''),'D',''),'E',''),'F',''),'G',''),'H',''),'I',''),'J','')
        ,'K',''),'L',''),'M',''),'N',''),'O',''),'P',''),'Q',''),'R',''),'S',''),'T','')
        ,'U',''),'V',''),'W',''),'X',''),'Y',''),'Z',''),'$',''),',',''),' ','') as float) 
        

        【讨论】:

        • 这个解决方案将永远困扰我的梦想。
        • 确实令人不安
        • 啊,LISP 令人兴奋的日子。
        • 我怎样才能取消看到这个?
        • 它既美丽又丑陋?。但说真的,出于性能和可读性的原因,不要将它用于真正的生产代码。
        【解决方案6】:

        input table

        如果您在图像中有上述数据,请使用以下查询

        select field_3 from table where PATINDEX('%[ ~`!@#$%^&*_()=+\|{};",<>/?a-z]%', field_3)=0
        

        结果会是这样的

        Result table

        【讨论】:

          【解决方案7】:
          select substring(
                          'jaksm234234',
                          patindex('%[0-9]%','jaksm234234'),
                          LEN('jaksm234234')-patindex('%[0-9]%','jaksm234234')+2
                          )
          

          【讨论】:

          • 我正在查看您的示例,如果该列不包含任何数字,它会转换为 int 错误。有什么想法吗?
          【解决方案8】:

          仅从字符串中提取数字。返回一个包含所有数字的字符串。示例:this1is2one345long6789number 将返回 123456789

          CREATE FUNCTION [dbo].[GetOnlyNumbers] (@Temp VARCHAR(1000))
          

          RETURNS VARCHAR (1000) AS BEGIN

              DECLARE @KeepValues AS VARCHAR(50)
              SET @KeepValues = '%[^0-9]%'
              WHILE PATINDEX(@KeepValues, @Temp) > 0
                  SET @Temp = STUFF(@Temp, PATINDEX(@KeepValues, @Temp), 1, '')
          
              RETURN @Temp
          END
          

          【讨论】:

            【解决方案9】:

            带有 patindex 的反向字符串的权利也适用于那些

            SELECT [Column], 
              CAST(RIGHT([Column], PATINDEX('%[0-9][^0-9]%', REVERSE([Column])+' ')) AS INT) as [Num]
            FROM (VALUES 
            ('abd738927'),
            ('jaksm234234'),
            ('hfk342'),
            ('ndma0834'),
            ('jon99322'),
            ) val([Column])
            
            Column Num
            abd738927 738927
            jaksm234234 234234
            hfk342 342
            ndma0834 834
            jon99322 99322

            【讨论】:

              猜你喜欢
              • 2014-11-18
              • 1970-01-01
              • 1970-01-01
              • 2021-09-15
              • 2014-04-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多