如何使用SQL或PL / SQL从字符串下面提取所有数字?
[6d(1.5h; 31h)] x(5至7)
[1d(8h; 24h; 48.5h; 72h; 96h)] x(1至5)
答案 0 :(得分:2)
您可以使用正则表达式和相关的层次结构查询来获取值:
Oracle设置:
CREATE TABLE table_name ( id, value ) AS
SELECT 1, '[ 6d (1.5h; 31h)] x (5 to 7)' FROM DUAL UNION ALL
SELECT 2, '[ 1d (8h; 24h; 48.5h; 72h; 96h)] x (1 to 5)' FROM DUAL;
查询:
SELECT id, COLUMN_VALUE
FROM table_name t
CROSS JOIN
TABLE(
CAST(
MULTISET(
SELECT REGEXP_SUBSTR( t.value, '\d+\.?\d*', 1, LEVEL )
FROM DUAL
CONNECT BY LEVEL <= REGEXP_COUNT( t.value, '\d+\.?\d*' )
) AS SYS.ODCINUMBERLIST
)
) n;
结果:
ID COLUMN_VALUE
--- ------------
1 6
1 1.5
1 31
1 5
1 7
2 1
2 8
2 24
2 48.5
2 72
2 96
2 1
2 5
查询2 :
SELECT REGEXP_SUBSTR( value, '\[\s*([0-9.]+)d\s*\((.*?)\)\]\s*x\s*\(([0-9.]+)\s*to\s*([0-9.]+)\)', 1, 1, NULL, 1 ) AS days,
REGEXP_REPLACE(
REGEXP_SUBSTR( value, '\[\s*([0-9.]+)d\s*\((.*?)\)\]\s*x\s*\(([0-9.]+)\s*to\s*([0-9.]+)\)', 1, 1, NULL, 2 ),
'[^0-9.;]'
)AS hours,
REGEXP_SUBSTR( value, '\[\s*([0-9.]+)d\s*\((.*?)\)\]\s*x\s*\(([0-9.]+)\s*to\s*([0-9.]+)\)', 1, 1, NULL, 3 ) AS x_from,
REGEXP_SUBSTR( value, '\[\s*([0-9.]+)d\s*\((.*?)\)\]\s*x\s*\(([0-9.]+)\s*to\s*([0-9.]+)\)', 1, 1, NULL, 4 ) AS x_to
FROM table_name t;
结果:
DAYS HOURS X_FROM X_TO
---- --------------- ------ ----
6 1.5;31 5 7
1 8;24;48.5;72;96 1 5
答案 1 :(得分:1)
您可以通过 regexp_replace 的作用来导出由定界符(在本例中为竖线)分隔的所有数字,如下所示:
select regexp_replace('[ 6d (1.5h; 31h)] x (5 to 7)','[^0-9.]+','|') str from dual union all
select regexp_replace('[ 1d (8h; 24h; 48.5h; 72h; 96h)] x (1 to 5)','[^0-9.]+','|') from dual;
STR
------------------
|6|1.5|31|5|7|
|1|8|24|48.5|72|96|1|5|