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

时间:2017-09-28 14:12:01

标签: mysql sql

如果我有这样的字符串:

CC123484556
CC492014512
BUXT122256690

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

SELECT LEFT(alloy , 4) FROM tbl 

所以期望的结果是:

1234
4920
1222

2 个答案:

答案 0 :(得分:2)

缓慢而丑陋:

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;

<强> Rextester Demo

生成所有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;

<强> Rextester Demo2

从头开始获取4个字符的子字符串,隐式转换为数字,获得最低的数字。

答案 1 :(得分:1)

使用locate()least()substr()

SQLFiddle Demo

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;

测试结果:

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)