Reputation: 3833
If I have something like table called mutable, for example, with this kind of data:
id size 1 100ml 2 30ml 3 6,7g 4 8,8kg 5 alfa 110v 6 beta 220v
How can I extract the number of a string and convert it to a float number. (At this case the ,
separates the decimal part from the integer one.
So, how can I perform a query to return something like this?:
id size finalSize 3 6,7g 6,7 4 8,8kg 8,8 2 30ml 30 1 100ml 100 5 alfa 110v 110 6 beta 220v 220
and this? (just the id`s):
id 3 4 2 1 5 6
P.S.: I need to do this with MySQL functions...
P.S.:2
I have tried search about match a regex using MySQL, but looks like there aren't functions to return the matched pattern.
Maybe if I create a function that replaces everthing that isn't a digit or ,
can solve the problem to me, but I couldn't find a way to do this. MYSQL REPLACE function doesn't use regex.
Upvotes: 1
Views: 4330
Reputation: 1
Also, I've modify again to extract only one number if the string contains more than one. If exist some character o string pre-differenciate, you can call the function with EXTRACT_NUMBER(SUBSTRING_INDEX(Notas,'CHARS',-1)) being CHARS the pre-character(s)
DELIMITER $$
DROP FUNCTION IF EXISTS `EXTRACT_NUMBER`$$
DELIMITER $$
CREATE FUNCTION EXTRACT_NUMBER(input VARCHAR(255))
RETURNS VARCHAR(255)
BEGIN
DECLARE output VARCHAR(255) DEFAULT '';
DECLARE iterator INT DEFAULT 1;
WHILE iterator < (LENGTH(input) + 1) DO
IF SUBSTRING(input, iterator, 1) IN (',', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ) THEN
IF (SUBSTRING(input, iterator, 1) = ',' AND output = '')
THEN SET output = '';
END IF;
SET output = CONCAT(output, SUBSTRING(input, iterator, 1));
END IF;
IF (SUBSTRING(input, iterator, 1) NOT IN (',', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ) AND output <> '')
THEN SET iterator = LENGTH(input);
END IF;
SET iterator = iterator + 1;
END WHILE;
RETURN replace(output,',','.');
END $$
Upvotes: 0
Reputation: 1
Great function bonCodigo!!!, but I want to report this modification in order to simplify the work:
DELIMITER $$
DROP FUNCTION IF EXISTS `EXTRACT_NUMBER`$$
DELIMITER $$
CREATE FUNCTION EXTRACT_NUMBER(input VARCHAR(255))
RETURNS VARCHAR(255)
BEGIN
DECLARE output VARCHAR(255) DEFAULT '';
DECLARE iterator INT DEFAULT 1;
WHILE iterator < (LENGTH(input) + 1) DO
IF SUBSTRING(input, iterator, 1) IN (',', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ) THEN
SET output = CONCAT(output, SUBSTRING(input, iterator, 1));
END IF;
SET iterator = iterator + 1;
END WHILE;
RETURN CONVERT(replace(output,',','.'), DECIMAL) ;
END $$
Upvotes: 0
Reputation: 14361
Here is a solution based on a function: The function was readily available in one of thes posts. So I only changed adding a comma
into the list as it works well :)
Query:
select id, size,
replace(STRIP_NON_DIGIT(size),',','.')
as final
from demo
;
Function:
CREATE FUNCTION STRIP_NON_DIGIT(input VARCHAR(255))
RETURNS VARCHAR(255)
BEGIN
DECLARE output VARCHAR(255) DEFAULT '';
DECLARE iterator INT DEFAULT 1;
WHILE iterator < (LENGTH(input) + 1) DO
IF SUBSTRING(input, iterator, 1) IN (',', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ) THEN
SET output = CONCAT(output, SUBSTRING(input, iterator, 1));
END IF;
SET iterator = iterator + 1;
END WHILE;
RETURN output;
END//
Results:
| ID | SIZE | FINAL |
--------------------------
| 3 | 6,7g | 6.7 |
| 4 | 8,8kg | 8.8 |
| 2 | 30ml | 30 |
| 1 | 100ml | 100 |
| 5 | alfa 110v | 110 |
| 6 | beta 220v | 220 |
As you mentioned yourself, MYSQL doesn't have the regex_replace
like Oracle
. Unless you want to use multiple number of replaces
(wouldn't want to assume how many), a funciton would come in handy for you.
Upvotes: 4
Reputation: 37233
try this
SELECT size,
@num := CONVERT(size, SIGNED) AS num_part,
SUBSTRING(size, LENGTH(@num) + 1) AS rest_of_string
FROM your_table;
Upvotes: 1