How to get only Digits from String in mysql?

How to get only Digits from String in mysql?

If the string starts with a number, then contains non-numeric characters, you can use the CAST() function or convert it to a numeric implicitly by adding a 0:

SELECT CAST(1234abc AS UNSIGNED); -- 1234
SELECT 1234abc+0; -- 1234

To extract numbers out of an arbitrary string you could add a custom function like this:

DELIMITER $$

CREATE FUNCTION `ExtractNumber`(in_string VARCHAR(50)) 
RETURNS INT
NO SQL
BEGIN
    DECLARE ctrNumber VARCHAR(50);
    DECLARE finNumber VARCHAR(50) DEFAULT ;
    DECLARE sChar VARCHAR(1);
    DECLARE inti INTEGER DEFAULT 1;

    IF LENGTH(in_string) > 0 THEN
        WHILE(inti <= LENGTH(in_string)) DO
            SET sChar = SUBSTRING(in_string, inti, 1);
            SET ctrNumber = FIND_IN_SET(sChar, 0,1,2,3,4,5,6,7,8,9); 
            IF ctrNumber > 0 THEN
                SET finNumber = CONCAT(finNumber, sChar);
            END IF;
            SET inti = inti + 1;
        END WHILE;
        RETURN CAST(finNumber AS UNSIGNED);
    ELSE
        RETURN 0;
    END IF;    
END$$

DELIMITER ;

Once the function is defined, you can use it in your query:

SELECT ExtractNumber(abc1234def) AS number; -- 1234

To whoever is still looking, use regex:

select REGEXP_SUBSTR(name,[0-9]+) as amount from `subscriptions`

How to get only Digits from String in mysql?

Based on Eugene Yarmash Answer. Here is a version of the custom function that extracts a decimal with two decimal places. Good for price extraction.

DELIMITER $$

CREATE FUNCTION `ExtractDecimal`(in_string VARCHAR(255)) 
RETURNS decimal(15,2)
NO SQL
BEGIN
    DECLARE ctrNumber VARCHAR(255);
    DECLARE in_string_parsed VARCHAR(255);
    DECLARE digitsAndDotsNumber VARCHAR(255) DEFAULT ;
    DECLARE finalNumber VARCHAR(255) DEFAULT ;
    DECLARE sChar VARCHAR(1);
    DECLARE inti INTEGER DEFAULT 1;
    DECLARE digitSequenceStarted boolean DEFAULT false;
    DECLARE negativeNumber boolean DEFAULT false;

    -- FIX FIND_IN_SET cannot find a comma ,
    SET in_string_parsed = replace(in_string,,,.);

    IF LENGTH(in_string_parsed) > 0 THEN
        -- extract digits and dots
        WHILE(inti <= LENGTH(in_string_parsed)) DO
            SET sChar = SUBSTRING(in_string_parsed, inti, 1);
            SET ctrNumber = FIND_IN_SET(sChar, 0,1,2,3,4,5,6,7,8,9,.); 
            IF ctrNumber > 0 AND (sChar != . OR LENGTH(digitsAndDotsNumber) > 0) THEN
                -- add first minus if needed
                IF digitSequenceStarted = false AND inti > 1 AND SUBSTRING(in_string_parsed, inti-1, 1) = - THEN
                    SET negativeNumber = true;
                END IF;

                SET digitSequenceStarted = true;
                SET digitsAndDotsNumber = CONCAT(digitsAndDotsNumber, sChar);
            ELSEIF digitSequenceStarted = true THEN
                SET inti = LENGTH(in_string_parsed);
            END IF;
            SET inti = inti + 1;
        END WHILE;

        -- remove dots from the end of number list
        SET inti = LENGTH(digitsAndDotsNumber);
        WHILE(inti > 0) DO
            IF(SUBSTRING(digitsAndDotsNumber, inti, 1) = .) THEN
                SET digitsAndDotsNumber = SUBSTRING(digitsAndDotsNumber, 1, inti-1);
                SET inti = inti - 1;
            ELSE
                SET inti = 0;
            END IF;
        END WHILE;

        -- extract decimal
        SET inti = 1;
        WHILE(inti <= LENGTH(digitsAndDotsNumber)-3) DO
            SET sChar = SUBSTRING(digitsAndDotsNumber, inti, 1);
            SET ctrNumber = FIND_IN_SET(sChar, 0,1,2,3,4,5,6,7,8,9); 
            IF ctrNumber > 0 THEN
                SET finalNumber = CONCAT(finalNumber, sChar);
            END IF;
            SET inti = inti + 1;
        END WHILE;

        SET finalNumber = CONCAT(finalNumber, RIGHT(digitsAndDotsNumber, 3));
        IF negativeNumber = true AND LENGTH(finalNumber) > 0 THEN
            SET finalNumber = CONCAT(-, finalNumber);
        END IF;

        IF LENGTH(finalNumber) = 0 THEN
            RETURN 0;
        END IF;

        RETURN CAST(finalNumber AS decimal(15,2));
    ELSE
        RETURN 0;
    END IF;    
END$$

DELIMITER ;

Tests:

select ExtractDecimal(1234); -- 1234.00
select ExtractDecimal(12.34); -- 12.34
select ExtractDecimal(1.234); -- 1234.00
select ExtractDecimal(1,234); -- 1234.00
select ExtractDecimal(1,111,234); -- 11111234.00
select ExtractDecimal(11,112,34); -- 11112.34
select ExtractDecimal(11,112,34 and 123123); -- 11112.34
select ExtractDecimal(-1); -- -1.00
select ExtractDecimal(hello. price is 123); -- 123.00
select ExtractDecimal(123,45,-); -- 123.45

Leave a Reply

Your email address will not be published. Required fields are marked *