我有一个相当大的数据库,其中一个列的字符串大部分只是整数,例如“1234”或“345”。然而,它们中的一些在它们之前具有弦(具有不同的长度),因此例如“a123”或“abc123”。
是否有一种智能方法来创建仅包含整数值的新列?那么,“abc123”会变成“123”吗?我知道我可以读取PHP中的所有行,然后使用正则表达式很容易地完成它但是我想看看是否有办法让SQL为我做这个。
答案 0 :(得分:1)
不幸的是,你不能仅仅在MySQL中做到这一点。 MySQL具有正则表达式匹配功能,但没有正则表达式替换功能。您最好的选择是使用PHP中的正则表达式来执行替换。 <子>(Source)子>
$sql = "SELECT `id`, `myMixedColumn` FROM `myTable` "
. "WHERE `myMixedColumn` NOT RLIKE '^[[:digit:]]+$'";
$r = mysql_query($sql);
$updates = array();
while ($row = mysql_fetch_assoc($r)) {
$updates = sprintf("UPDATE `myTable` SET `myIntField` = %s WHERE `id` = %d",
preg_replace("@\\D@", "", $row['myMixedColumn']),
$row['id']
);
}
答案 1 :(得分:1)
如果你真的想在SQL中这样做,只是为了不在PHP中做,你可以创建一个小函数,直到MySQL实现正则表达式替换,但我不打算在性能上做任何事情。
这样的东西只有在字母开头的时候才有效,并且除了[a-zA-Z]之外没有其他字符。你必须检查它在不同的字符集中的运行方式。
CREATE FUNCTION last_letter(s VARCHAR(100)) RETURNS INT
BEGIN
DECLARE last, current INT default 0;
DECLARE letter_a INT;
DECLARE letter_z INT;
DECLARE letter_iter INT;
SELECT ord('a') INTO letter_a;
SELECT ord('z') INTO letter_z;
SET letter_iter = letter_a;
# Will loop for all letters a to z
WHILE letter_iter <= letter_z DO
# Will get the last case-insensitive occurrence of a letter
SELECT LOCATE(CHAR(letter_iter), REVERSE(LOWER(s))) INTO current;
IF current > 0 THEN
SELECT LENGTH(s) - current + 1 INTO current;
END IF;
# Was that the rightmost letter?
IF current > last THEN
SET last = current;
END IF;
SET letter_iter = letter_iter + 1;
END WHILE;
# Return the max we found
RETURN last;
END; //
然后获取整数值:
UPDATE test_table SET int_result =
CAST(SUBSTR(str_value, last_letter(str_value) + 1) AS SIGNED);