将字符串转换为数值,从“:”的左侧拉出,然后再拉至“:”的右侧

时间:2018-07-03 21:32:44

标签: sql oracle regexp-substr

Text_value是具有字符串值的列。我只需要查找':'并将左侧与右侧分开并转换为数字,这样我就可以执行简单的计算。如果':'不存在,我希望返回null。我正在Oracle SQL Developer中创建视图

Text_Value (Column)    
124  
7  
55:20  
73:00  
106:24  

这是我的代码:

to_number(REGEXP_SUBSTR(b.text_value,'[^:]*',1,1)) AS Num,
to_number(REGEXP_SUBSTR(B.text_value,'[^:]*$'))  AS FRACTION2

这些是我的结果:

results in Oracle

我希望不包含“:”的text_values返回null。这就是我想看到的。

3 个答案:

答案 0 :(得分:1)

您可以使用正则表达式^(\d+):(\d+)$来检查由冒号分隔的两个数字,如下所示:

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE table_name ( text_value ) AS
SELECT '124' FROM DUAL UNION ALL
SELECT '7' FROM DUAL UNION ALL
SELECT '55:20' FROM DUAL UNION ALL
SELECT '73:00' FROM DUAL UNION ALL
SELECT '106:24' FROM DUAL;

查询1

SELECT text_value,
       TO_NUMBER( REGEXP_SUBSTR( text_value, '^(\d+):(\d+)$', 1, 1, NULL, 1 ) ) AS num,
       TO_NUMBER( REGEXP_SUBSTR( text_value, '^(\d+):(\d+)$', 1, 1, NULL, 2 ) ) AS fraction2
FROM   table_name

Results

| TEXT_VALUE |    NUM | FRACTION2 |
|------------|--------|-----------|
|        124 | (null) |    (null) |
|          7 | (null) |    (null) |
|      55:20 |     55 |        20 |
|      73:00 |     73 |         0 |
|     106:24 |    106 |        24 |

答案 1 :(得分:1)

您可以避免使用正则表达式,而改用instrsubstr

select text_value,
  to_number(case when instr(text_value, ':') > 0
    then substr(text_value, 1, instr(text_value, ':') - 1)
    else null end) as num,
  to_number(case when instr(text_value, ':') > 0
    then substr(text_value, instr(text_value, ':') + 1)
    else null end) as fraction2
from b;

这执行了更多的单个函数调用,但是它们可能仍比正则表达式执行得更好,并且您可以将instr移入内联视图中,因此您不必这样做四次(尽管优化程序可能仍会缓存结果。)

SQL Fiddle demo使用图像中的一些值以及您没有引用的其他两个变体,并且您可能希望以不同的方式处理这些变体。

如果未按需要处理这些情况,则可以调整大小写表达条件,例如将num更改为> 1,并将fraction2与字符串长度进行比较-但这取决于您要查看的内容(以及这些情况是否可能存在)。

答案 2 :(得分:1)

您快到了。您只需测试一下字符串中是否包含10000,20000,30000,40000,50000 ,然后再提取字符串的“ seconds”部分:

for (int i = 0; i < data.lenght(); i++ ) {
    data.set(i, data.get(i).replace("ksh", ""));
    data.set(i, data.get(i).replace(",",""));
}

SQLFiddle here

编辑

如果更改第二个正则表达式以包含而不是排除冒号,则可以摆脱:,然后使用SELECT TEXT_VALUE, TO_NUMBER(REGEXP_SUBSTR(text_value,'[^:]*',1,1)) AS MINUTES, CASE WHEN INSTR(TEXT_VALUE, ':') > 0 THEN TO_NUMBER(REGEXP_SUBSTR(text_value,'[^:]*$')) ELSE NULL END AS SECONDS FROM T; TEXT_VALUE MINUTES SECONDS 11 11 (null) 00:38 0 38 (null) (null) (null) 69:18 69 18 74:11 74 11 83:43 83 43 00:51 0 51 00:45 0 45 01:42 1 42 7 7 (null) 78:30 78 30 50 50 (null) 03:08 3 8 70:42 70 42 72:24 72 24 123 123 (null) 55:20 55 20 来抓取CASE之后的所有字符:

SUBSTR

Revised SQLFiddle here