同时替换多个值 - 为了将字符串转换为数字

Posted

技术标签:

【中文标题】同时替换多个值 - 为了将字符串转换为数字【英文标题】: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

【问题讨论】:

【参考方案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

参考:

T-SQL strip all non-alpha and non-numeric characters

【讨论】:

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

【讨论】:

以上是关于同时替换多个值 - 为了将字符串转换为数字的主要内容,如果未能解决你的问题,请参考以下文章

sql中如何把字符串转换为数字

php,怎么将把数字传换成字符串?

js中怎么把时间时间字符串类型转换成时间类型

sqlserver中如何把字符串转换成数字

oracle sql字符串转数字问题

js中字符串转数字,并且保留1位小数