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

Extracting numerical values from mySQL column string value

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

示例: “24,175”

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

示例:将“24,175”转换为

24 岁
175 作为权重

这样我就可以写一个类似于下面的查询

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

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

我无法修改我正在使用的table/environment

我只能访问查询。

我正在考虑这样解决

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

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

使用 CAST(age AS INT) CAST(weight AS INT) 将年龄子串和体重子串转换为数字

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

如果我做错了什么,请指正。 usable/supported的所有功能都是mySQL吗? (右,左,CHARINDEX)这行得通吗?

异常:此列的另一个值可能是 "unknown"。如果我们试图检查 的索引,如果它不存在于字符串中,这会导致错误吗?有没有办法在结果中包含 "unknown" 个案例并让它输出 "error, person not recognized"

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

在 MySQL 中使用 LOCATE 而不是 Charindex

还要注意 CAST 函数

你也可以像这样用 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]>

您可以在 where 子句中完成所有操作:

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

请注意,+ 0 会静默转换为整数。而且,substring_index()比SQL服务器端的功能方便多了。

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

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 子句之后。

您还可以使用 VIRTUAL PERSISTENT COLUMNS 来计算 otomatis 字段,还可以在每个 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]>