Mysql 从字符串中选择前4个数字

Mysql 从字符串中选择前4个数字,mysql,sql,Mysql,Sql,如果我有这样的字符串: CC123484556 CC492014512 BUXT122256690 我如何在MySQL中操作这样的代码来提取前4个值(即数字)?在其他行中,数字前面有各种字母,但最重要的是显示的前4个数字 SELECT LEFT(alloy , 4) FROM tbl 因此,预期的结果将是: 1234 4920 1222 又慢又丑: SELECT col, SUBSTRING(tab.col, MIN(LOCATE(four_digits, tab.col,

如果我有这样的字符串:

CC123484556
CC492014512
BUXT122256690
我如何在MySQL中操作这样的代码来提取前4个值(即数字)?在其他行中,数字前面有各种字母,但最重要的是显示的前4个数字

SELECT LEFT(alloy , 4) FROM tbl 
因此,预期的结果将是:

1234
4920
1222
又慢又丑:

SELECT col,
       SUBSTRING(tab.col, MIN(LOCATE(four_digits, tab.col,1)), 4) + 0 AS result
FROM  (SELECT 'CC123484556' AS col UNION ALL
       SELECT 'CC492014512' UNION ALL
       SELECT 'BUXT122256690' UNION ALL
       SELECT 'abced') tab
CROSS JOIN (
   SELECT  CONCAT(d1.z, d2.z, d3.z, d4.z) AS four_digits
   FROM (SELECT '1' AS z UNION SELECT '2' UNION SELECT '3' UNION
            SELECT '4' UNION SELECT '5' UNION SELECT '6' UNION
            SELECT '7' UNION SELECT '8' UNION SELECT '9' UNION SELECT '0') d1
  CROSS JOIN (SELECT '1' AS z UNION SELECT '2' UNION SELECT '3' UNION
            SELECT '4' UNION SELECT '5' UNION SELECT '6' UNION
            SELECT '7' UNION SELECT '8' UNION SELECT '9' UNION SELECT '0') d2
  CROSS JOIN (SELECT '1' AS z UNION SELECT '2' UNION SELECT '3' UNION
            SELECT '4' UNION SELECT '5' UNION SELECT '6' UNION
            SELECT '7' UNION SELECT '8' UNION SELECT '9' UNION SELECT '0') d3
  CROSS JOIN (SELECT '1' AS z UNION SELECT '2' UNION SELECT '3' UNION
            SELECT '4' UNION SELECT '5' UNION SELECT '6' UNION
            SELECT '7' UNION SELECT '8' UNION SELECT '9' UNION SELECT '0') d4
 ) sub
WHERE LOCATE(four_digits, tab.col,1) > 0
GROUP BY col;
生成所有4位数字组合,在字符串中定位它们,并获得索引最低的子字符串

编辑:

快一点的方法:

SELECT col, SUBSTRING(col, MIN(i), 4) + 0 AS r
FROM (
    SELECT col, SUBSTRING(tab.col, i , 4) + 0 AS result, i
    FROM tab
    CROSS JOIN (
       SELECT  CONCAT(d1.z, d2.z)+1 AS i
       FROM (SELECT '1' AS z UNION SELECT '2' UNION SELECT '3' UNION
                SELECT '4' UNION SELECT '5' UNION SELECT '6' UNION
                SELECT '7' UNION SELECT '8' UNION SELECT '9' UNION SELECT '0') d1
      CROSS JOIN (SELECT '1' AS z UNION SELECT '2' UNION SELECT '3' UNION
                SELECT '4' UNION SELECT '5' UNION SELECT '6' UNION
                SELECT '7' UNION SELECT '8' UNION SELECT '9' UNION SELECT '0') d2
     ) sub
     WHERE  i <= LENGTH(tab.col)-1
) sub
WHERE result <> 0
GROUP BY col;
从开始处获取4个字符的子字符串,隐式转换为数字,使用和获取i最少的数字

测试结果:

输出:

mysql> select * from test;
+---------------+
| col           |
+---------------+
| CC123484556   |
| CC492014512   |
| BUXT122256690 |
+---------------+
3 rows in set (0.00 sec)

mysql> select col,SUBSTR(col,LEAST(
    ->     if (Locate(0,col) >0,Locate(0,col),999),
    ->     if (Locate(1,col) >0,Locate(1,col),999),
    ->     if (Locate(2,col) >0,Locate(2,col),999),
    ->     if (Locate(3,col) >0,Locate(3,col),999),
    ->     if (Locate(4,col) >0,Locate(4,col),999),
    ->     if (Locate(5,col) >0,Locate(5,col),999),
    ->     if (Locate(6,col) >0,Locate(6,col),999),
    ->     if (Locate(7,col) >0,Locate(7,col),999),
    ->     if (Locate(8,col) >0,Locate(8,col),999),
    ->     if (Locate(9,col) >0,Locate(9,col),999)
    ->   ),4) as result from test;
+---------------+--------+
| col           | result |
+---------------+--------+
| CC123484556   | 1234   |
| CC492014512   | 4920   |
| BUXT122256690 | 1222   |
+---------------+--------+
3 rows in set (0.00 sec)

可能最简单的方法是用空格替换所有非数字字符,并在结果上使用左…,4+0。不幸的是,MySQL不支持REGEX_REPLACE。有趣的方法:@lad2025谢谢,有时会想到它,但在需要时它不会出现:
mysql> create table test ( col varchar(15));
Query OK, 0 rows affected (0.70 sec)

mysql> insert into test (col) values 
    -> ('CC123484556'),
    -> ('CC492014512'),
    -> ('BUXT122256690');
Query OK, 3 rows affected (0.13 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> select * from test;
+---------------+
| col           |
+---------------+
| CC123484556   |
| CC492014512   |
| BUXT122256690 |
+---------------+
3 rows in set (0.00 sec)

mysql> select col,SUBSTR(col,LEAST(
    ->     if (Locate(0,col) >0,Locate(0,col),999),
    ->     if (Locate(1,col) >0,Locate(1,col),999),
    ->     if (Locate(2,col) >0,Locate(2,col),999),
    ->     if (Locate(3,col) >0,Locate(3,col),999),
    ->     if (Locate(4,col) >0,Locate(4,col),999),
    ->     if (Locate(5,col) >0,Locate(5,col),999),
    ->     if (Locate(6,col) >0,Locate(6,col),999),
    ->     if (Locate(7,col) >0,Locate(7,col),999),
    ->     if (Locate(8,col) >0,Locate(8,col),999),
    ->     if (Locate(9,col) >0,Locate(9,col),999)
    ->   ),4) as result from test;
+---------------+--------+
| col           | result |
+---------------+--------+
| CC123484556   | 1234   |
| CC492014512   | 4920   |
| BUXT122256690 | 1222   |
+---------------+--------+
3 rows in set (0.00 sec)