从mySQL列字符串值中提取数值

时间:2016-07-02 17:16:13

标签: mysql sql performance sql-function

mySQL数据库中有一个“person”列,用逗号分隔的字符串表示一个人的年龄和体重。

实施例: “24175”

我希望能够分离并提取这些值并将其转换为数字。

示例:将“24,175”变为

年龄为24岁 175重量

这样我就可以编写类似于以下内容的查询

SELECT person 
FROM TABLE
WHERE age>140 OR weight>1000

我希望能够检查不可能的值。即年龄> 140或体重> 1000。

我无法修改我正在使用的表/环境

我只能访问查询。

我正在考虑以这种方式解决它

找到逗号所在的索引。 CHARINDEX( '',人)

使用LEFT,RIGHT,CAST和CHARINDEX(',',person)将字符串拆分为子字符串

使用CAST(年龄AS INT)CAST(权重AS INT)将年龄子字符串和权重子字符串转换为数字

SELECT person
FROM TABLE
WHERE CAST(LEFT(person,CHARINDEX(',',person) AS INT)>150 OR CAST(RIGHT(person,CHARINDEX(',',person) AS INT) >1000

如果我做错了什么请纠正我。 mySQL是否可以使用/支持所有功能? (右,左,CHARINDEX)这有用吗?

例外:此列的另一个值可能是“未知”。如果我们试图检查索引,如果字符串中不存在,这会导致错误吗?有没有办法在结果中包含“未知”案例并让它输出“错误,未被识别的人”的消息

4 个答案:

答案 0 :(得分:0)

SELECT person
FROM TABLE
WHERE CAST(LEFT(person,LOCATE(',',person) AS INTEGER)>150 OR CAST(RIGHT(person,(LOCATE(',',person)+1) AS INTEGER) >1000

而不是Char索引使用LOCATE im MqSQL

另请注意CAST功能

答案 1 :(得分:0)

您还可以使用 SUBSTR_INDEX 进行拆分:

MariaDB [yourschema]> SELECT * FROM spliit;
+----+--------+
| id | d      |
+----+--------+
|  1 | 24,175 |
+----+--------+
1 row in set (0.03 sec)



MariaDB [yourschema]> SELECT
    ->     SUBSTRING_INDEX(d, ',', 1) AS age
    ->   , SUBSTRING_INDEX(d, ',', -1) AS weight
    ->
    -> FROM spliit;
+------+--------+
| age  | weight |
+------+--------+
| 24   | 175    |
+------+--------+
1 row in set (0.00 sec)

MariaDB [yourschema]>

<强>样品

是的,您可以在MySQL中直接计算

MariaDB [yourschema]> SELECT
    ->     SUBSTRING_INDEX(d, ',', 1)  + 2 AS age
    ->   , SUBSTRING_INDEX(d, ',', 1)  * 12 AS `month`
    ->   , SUBSTRING_INDEX(d, ',', -1) + 3 AS weight
    -> FROM spliit;

+------+-------+--------+
| age  | month | weight |
+------+-------+--------+
|   26 |   288 |    178 |
+------+-------+--------+
1 row in set, 1 warning (0.03 sec)

MariaDB [yourschema]>

答案 2 :(得分:0)

您可以在where子句中执行此操作:

where substring_index(person, ',', 1) + 0 > 140 or
      substring_index(person, ',' -1) + 0 > 1000

请注意+ 0执行静默转换为整数。并且,substring_index()比SQL Server中的函数更方便。

您可以轻松地将此逻辑合并到视图中:

create view v_table as
     select t.*,
            substring_index(person, ',', 1) + 0 as age,
            substring_index(person, ',' -1) + 0 as weight
     from table t;

如果要在视图中过滤掉错误值,可以使用MySQL扩展并添加:

having age > 140 or weight > 1000

from子句之后。

答案 3 :(得分:0)

您还可以使用计算自动字段的VIRTUAL PERSITENT COLUMNS,也可以在每个substr / Integer上使用INDEX。

<强>样品

MariaDB [yourschema]> CREATE TABLE `splitit` (
    ->   `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    ->   `d` VARCHAR(32) DEFAULT NULL,
    ->   age INT(11) AS (SUBSTRING_INDEX(d, ',', 1)) PERSISTENT,
    ->   weight INT(5) AS (SUBSTRING_INDEX(d, ',', -1)) PERSISTENT,
    ->   PRIMARY KEY (`id`),
    ->   INDEX idx_age (age),
    ->   INDEX idx_weight (weight)
    -> ) ENGINE=INNODB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.79 sec)

MariaDB [yourschema]> INSERT INTO splitit (d) VALUES ('11,234'),('2,66'),('5,2');
Query OK, 3 rows affected (0.06 sec)
Records: 3  Duplicates: 0  Warnings: 0

MariaDB [yourschema]> SELECT * FROM splitit;
+----+--------+------+--------+
| id | d      | age  | weight |
+----+--------+------+--------+
|  1 | 11,234 |   11 |    234 |
|  2 | 2,66   |    2 |     66 |
|  3 | 5,2    |    5 |      2 |
+----+--------+------+--------+
3 rows in set (0.00 sec)

MariaDB [yourschema]>