43

I am trying to convert a varchar field to a number, however, there is a set of common characters inside that field that need to be removed in order for me to successfully convert it to numeric.

the name of the field is UKSellPrice1

I need to remove the following strings from UKSellPrice1 BEFORE converting it to numeric:

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

How can I get this done?

at the moment I have the following: enter image description here

;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

3 Answers 3

72

I can think of two approaches.

The first is to use a bunch of nested replace() statements:

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

and so on.

The second is to find the first digit and try converting from there. This requires complicated logic with patindex(). Here is an example:

select cast(left(substring(col, patindex('%[0-9]%', col), 1000),
                 patindex('%[^0-9]%', substring(col, patindex('%[0-9]%', col), 1000)) - 1
                ) as int)
Sign up to request clarification or add additional context in comments.

Comments

7

You could do this. Create a function to strip a way the unwanted chars like this:

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

Then call the scalared function on the column with a pattern like this:

;WITH R0 AS (

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

Reference:

1 Comment

select dbo.[fnRemovePatternFromString]('120', '%[£$#N/A.00]%') gives 12 while one expects 120 so this solution should actually be used for single character replacements only
1

Inspired by @Arion above (thanks). This is the equivalent of (n) number of REPLACE(REPLACE(REPLACE())) calls, so just cleans up the code really nicely. I've swapped out STUFF() for REPLACE() so it's slightly more general use than your example above. Tested working (for my data sets), but I'm not a SQL guru, so YMMV. Also, since it just uses REPLACE() under the hood this handles Replacement with any size string, not just 1 char (as with @Arion's example).

/*
.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

1 Comment

Does the documentation style of the function supported by some documentation generator and if so, what is that documentation generator's name?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.