【问题标题】:replace multiple values at the same time - in order to convert a string to a number同时替换多个值 - 为了将字符串转换为数字
【发布时间】:2014-04-22 11:35:58
【问题描述】:

我正在尝试将 varchar 字段转换为数字,但是,需要删除该字段内的一组常用字符才能成功将其转换为数字。

该字段的名称是 UKSellPrice1

在将其转换为数字之前,我需要从 UKSellPrice1 中删除以下字符串:

'.00'
'£'
'n/a'
'$'
'#N/A'

我怎样才能完成这项工作?

目前我有以下内容:

;WITH R0 AS (

SELECT StyleCode
      ,ColourCode       
      ,UKSellPrice1= CASE WHEN CHARINDEX('.00',UKSellPrice1,1) > 0 
                          THEN REPLACE (UKSellPrice1,'.00','') 
                          ELSE UKSellPrice1 END
      ,UKSellPrice2
 FROM dbo.RangePlan
)
SELECT * 
FROM R0

【问题讨论】:

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


    【解决方案1】:

    我可以想到两种方法。

    首先是使用一堆嵌套的replace()语句:

    select replace(replace(replace(col, '$', ''), '£', ''), 'n/a', '')
    

    等等。

    第二个是找到第一个数字并尝试从那里转换。这需要patindex() 的复杂逻辑。这是一个例子:

    select cast(left(substring(col, patindex('%[0-9]%', col), 1000),
                     patindex('%[^0-9]%', substring(col, patindex('%[0-9]%', col), 1000)) - 1
                    ) as int)
    

    【讨论】:

      【解决方案2】:

      你可以这样做。创建一个函数来去除不需要的字符,如下所示:

      CREATE FUNCTION [dbo].[fnRemovePatternFromString](@BUFFER VARCHAR(MAX), @PATTERN VARCHAR(128)) RETURNS VARCHAR(MAX) AS
      BEGIN
          DECLARE @POS INT = PATINDEX(@PATTERN, @BUFFER)
          WHILE @POS > 0 BEGIN
              SET @BUFFER = STUFF(@BUFFER, @POS, 1, '')
              SET @POS = PATINDEX(@PATTERN, @BUFFER)
          END
          RETURN @BUFFER
      END
      

      然后使用这样的模式调用列上的标量函数:

      ;WITH R0 AS (
      
      SELECT StyleCode
            ,ColourCode       
            ,UKSellPrice1= CAST(dbo.fnRemovePatternFromString(UKSellPrice1,'%[£$#N/A.00]%') AS INT)
            ,UKSellPrice2
       FROM dbo.RangePlan
      )
      SELECT * 
      FROM R0
      

      参考:

      【讨论】:

      • select dbo.[fnRemovePatternFromString]('120', '%[£$#N/A.00]%') 给出 12 而人们期望 120 所以这个解决方案实际上应该用于单个字符仅替换
      【解决方案3】:

      灵感来自@Arion above(谢谢)。 这相当于 (n) 次 REPLACE(REPLACE(REPLACE())) 调用, 所以只是很好地清理了代码。 我已经将 STUFF() 换成了 REPLACE() 所以它比你上面的例子更通用。测试工作(对于我的数据集),但我不是 SQL 专家,所以 YMMV。此外,由于它只是在后台使用 REPLACE(),因此它可以处理任意大小的字符串替换,而不仅仅是 1 个字符(如 @Arion 的示例)。

      /*
      .SYNOPSIS
          FIND/REPLACE MULTIPLE VALUES FROM A STRING
      
      .DESCRIPTION
          Walk through the @FINDChars pattern, one character at a time.
          Do a find + REPLACE() on each of those characters in the string.
      
      .EXAMPLE
          [dbo].[fnFindReplaceAnyMatch](MyColumnName, '(''")', '')
      */
      CREATE FUNCTION [dbo].[fnFindReplaceAnyMatch](
          @BUFFER         VARCHAR(MAX), 
          @FINDChars      VARCHAR(128),
          @REPLACEChar    VARCHAR(128)
      ) RETURNS VARCHAR(MAX) AS
      BEGIN
          DECLARE @SingleCharPattern VARCHAR(1);
          DECLARE @PatternIndex INT = 0;
          WHILE @PatternIndex <= LEN(@FINDChars) BEGIN
              SET @SingleCharPattern = SUBSTRING(@FINDChars, @PatternIndex, 1);
              SET @BUFFER = REPLACE(@BUFFER, @SingleCharPattern, @REPLACEChar);
              SET @PatternIndex = @PatternIndex + 1;
          END
          RETURN @BUFFER
      END
      GO
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-10
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 2020-08-31
        • 2021-04-18
        • 2013-05-25
        相关资源
        最近更新 更多