同时替换多个值 - 为了将字符串转换为数字
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
【讨论】:
以上是关于同时替换多个值 - 为了将字符串转换为数字的主要内容,如果未能解决你的问题,请参考以下文章