Как вы извлекаете числовое значение из строки в запросе MySQL?
У меня есть таблица с двумя столбцами: price (int) и price_display (varchar).
цена - это фактическая цифровая цена, например. "9990"
price_display - это визуальное представление, например. "$ 9.99" или "9.99Fr"
Мне удалось подтвердить совпадение двух столбцов через regexp:
price_display not regexp формат (цена/1000, 2)
Но в случае несоответствия я хочу извлечь значение из столбца price_display и установить его в столбец цены, все в контексте оператора обновления. Я не смог понять, как это сделать.
Спасибо.
Ответы
Ответ 1
Эта функция выполняет задание только возвращать цифры 0-9 из строки, что прекрасно выполняет задание для решения вашей проблемы, независимо от того, какие префиксы или постовые есть у вас.
http://www.artfulsoftware.com/infotree/queries.php?&bw=1280#815
Скопировано здесь для справки:
SET GLOBAL log_bin_trust_function_creators=1;
DROP FUNCTION IF EXISTS digits;
DELIMITER |
CREATE FUNCTION digits( str CHAR(32) ) RETURNS CHAR(32)
BEGIN
DECLARE i, len SMALLINT DEFAULT 1;
DECLARE ret CHAR(32) DEFAULT '';
DECLARE c CHAR(1);
IF str IS NULL
THEN
RETURN "";
END IF;
SET len = CHAR_LENGTH( str );
REPEAT
BEGIN
SET c = MID( str, i, 1 );
IF c BETWEEN '0' AND '9' THEN
SET ret=CONCAT(ret,c);
END IF;
SET i = i + 1;
END;
UNTIL i > len END REPEAT;
RETURN ret;
END |
DELIMITER ;
SELECT digits('$10.00Fr');
#returns 1000
Ответ 2
Один подход заключается в использовании REPLACE():
UPDATE my_table
SET price = replace(replace(replace(price_display,'Fr',''),'$',''),'.','')
WHERE price_display not regexp format(price/1000, 2);
Это работает для данных, предоставленных вами:
'$9.99'
'9.99Fr'
Оба результата приводят к 999 в моем тесте. С таким обновлением важно обязательно сначала создать резервную копию базы данных и быть в курсе форматов элементов. Вы можете увидеть все "baddies", выполнив этот запрос:
SELECT DISTINCT price_display
FROM my_table
WHERE price_display not regexp format(price/1000, 2)
ORDER BY price_display;
Ответ 3
Для меня CASTING поле выполнило трюк:
CAST( price AS UNSIGNED )
//Для положительного целого числа
CAST( price AS SIGNED )
//Для отрицательного и положительного целых чисел
IF(CAST(price AS UNSIGNED)=0,REVERSE(CAST(REVERSE(price) AS UNSIGNED)),CAST(price AS UNSIGNED))
//Исправлено, когда цена начинается с чего-то еще, а затем цифры
Подробнее см.:
https://dev.mysql.com/doc/refman/5.0/en/cast-functions.html
Ответ 4
Я создаю процедуру, которая обнаруживает первое число в строке и возвращает это, если не возвращает 0.
DROP FUNCTION IF EXISTS extractNumber;
DELIMITER //
CREATE FUNCTION extractNumber (string1 VARCHAR(255)) RETURNS INT(11)
BEGIN
DECLARE position, result, longitude INT(11) DEFAULT 0;
DECLARE string2 VARCHAR(255);
SET longitude = LENGTH(string1);
SET result = CONVERT(string1, SIGNED);
IF result = 0 THEN
IF string1 REGEXP('[0-9]') THEN
SET position = 2;
checkString:WHILE position <= longitude DO
SET string2 = SUBSTR(string1 FROM position);
IF CONVERT(string2, SIGNED) != 0 THEN
SET result = CONVERT(string2, SIGNED);
LEAVE checkString;
END IF;
SET position = position + 1;
END WHILE;
END IF;
END IF;
RETURN result;
END //
DELIMITER ;
Ответ 5
Возвращает последний номер из строки:
CREATE FUNCTION getLastNumber(str VARCHAR(255)) RETURNS INT(11)
DELIMETER //
BEGIN
DECLARE last_number, str_length, position INT(11) DEFAULT 0;
DECLARE temp_char VARCHAR(1);
DECLARE temp_char_before VARCHAR(1);
IF str IS NULL THEN
RETURN -1;
END IF;
SET str_length = LENGTH(str);
WHILE position <= str_length DO
SET temp_char = MID(str, position, 1);
IF position > 0 THEN
SET temp_char_before = MID(str, position - 1, 1);
END IF;
IF temp_char BETWEEN '0' AND '9' THEN
SET last_number = last_number * 10 + temp_char;
END IF;
IF (temp_char_before NOT BETWEEN '0' AND '9') AND
(temp_char BETWEEN '0' AND '9') THEN
SET last_number = temp_char;
END IF;
SET position = position + 1;
END WHILE;
RETURN last_number;
END//
DELIMETER;
Затем вызовите следующие функции:
выберите getLastNumber ( "ssss111www222w" );
печать 222
выберите getLastNumber ( "ssss111www222www3332" );
print 3332
Ответ 6
Это "ужас кодирования", схемы реляционных баз данных должны быть написаны так: NOT!
Вам нужно написать сложный и ненужный код для проверки данных.
Попробуйте что-то вроде этого:
SELECT CONCAT('$',(price/1000)) AS Price FROM ...
Кроме того, вместо целых чисел вы можете использовать float
, double
или real
.
Если вам нужно сохранить данные о валюте, вы можете подумать о добавлении поля валюты или использовать функции языковых систем для отображения в правильном формате.