在SQL中解析字符串中的整数

时间:2008-11-10 00:30:53

标签: mysql

我有一个相当大的数据库,其中一个列的字符串大部分只是整数,例如“1234”或“345”。然而,它们中的一些在它们之前具有弦(具有不同的长度),因此例如“a123”或“abc123”。

是否有一种智能方法来创建仅包含整数值的新列?那么,“abc123”会变成“123”吗?我知道我可以读取PHP中的所有行,然后使用正则表达式很容易地完成它但是我想看看是否有办法让SQL为我做这个。

2 个答案:

答案 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);