我有VARCHAR2(5000 CHAR)列包含几个句子的表。某处在这样的句子的数量显示,后跟另一个号码。我想选择这些数字和他们分开。不知道如何在sqlplus的Oracle 11g做到这一点。
我想我应该用功能,如SUBSTR, REGEXP_SUBSTR, INSTR
。不知道这是最适合这个工作。
列是这样的:
blah bahwl balwo hxkswl blahxhsh alshbhe NUM 40003.26 in 4 pieces. etc
bwh bahwl bafado hxkswl alshbhe NUM 6006.16 in 9 pieces. etc
badh baadfl balwo hxkswl blahxhsh alshbhe NUM 200 in 30 pieces. etc
bfda bdafl hxkswl NUM 33 in 4 pieces. etc
blcfh bfdwl bfdlwo alshbhe NUM 54545.01 in 700 pieces. etc
所以,我想搜索和NUM后直接选择号码,然后选择“中”之间以及“碎片”的数量,然后除以这些数字。
select .... 40003.26 / 4
select .... 6006,16 / 9
select .... 200 / 30
等等
任何帮助赞赏和蔼
您可以使用qazxsw POI,qazxsw POI与qazxsw POI /如下regexp_substr
贡献
regexp_replace
l
此选项选择输入字符串的rtrim
部分,多次NUM出现在那里(这就是with t1 as
(select 'blah bahwl balwo hxkswl blahxhsh alshbhe NUM 40003.26 in 4 pieces. etc
bwh bahwl bafado hxkswl alshbhe NUM 6006.16 in 9 pieces. etc
badh baadfl balwo hxkswl blahxhsh alshbhe NUM 200 in 30 pieces. etc
bfda bdafl hxkswl NUM 33 in 4 pieces. etc
blcfh bfdwl bfdlwo alshbhe NUM 54545.01 in 700 pieces. etc' as str
from dual),
t2 as
(select regexp_substr(str, '(.*)pieces.*', 1, level) as str
from t1
cross join dual
connect by level <= regexp_count(str, 'pieces')),
t3 as
(select str,
regexp_replace(str, '[^0-9]in[^0-9]', '/') str1,
regexp_substr(str, '[^0-9]*') str2,
regexp_substr(str, '[^0-9]*$') str3
from t2)
select rtrim(ltrim(str1, str2), str3) as "Result String" from t3
Result String
-------------
40003.26/4
6006.16/9
200/30
33/4
54545.01/700
CTE一样)。最终Demo(线13以后)提取数字值和将其划分,以产生结果。
NUM blabla
如果你能保证所有的(我的意思是ALL)的行会像你所描述的一个片段:INTER
其中SELECT
是两个数与第二数不为0(这样我们就不会除以0),那么你可以使用XMLQuery对于这一点,就像这样:
SQL> with test (col) as
2 (select 'blah bahwl balwo hxkswl blahxhsh alshbhe NUM 40003.26 in 4 pieces. etc
3 bwh bahwl bafado hxkswl alshbhe NUM 6006.16 in 9 pieces. etc
4 badh baadfl balwo hxkswl blahxhsh alshbhe NUM 200 in 30 pieces. etc
5 bfda bdafl hxkswl NUM 33 in 4 pieces. etc
6 blcfh bfdwl bfdlwo alshbhe NUM 54545.01 in 700 pieces. etc' from dual
7 ),
8 inter as
9 (select regexp_substr(col, 'NUM \d+(\.\d+)? in \d+', 1, level) res
10 from test
11 connect by level <= regexp_count(col, 'NUM')
12 )
13 select res,
14 regexp_substr(res, '\d+(\.\d+)?') c1,
15 regexp_substr(res, '\d+$') c2,
16 --
17 round(to_number(regexp_substr(res, '\d+(\.\d+)?'), '99999999D99',
18 ' NLS_NUMERIC_CHARACTERS = ''.,''') /
19 to_number(regexp_substr(res, '\d+$')), 2) result
20 from inter;
RES C1 C2 RESULT
-------------------- ---------- ---------- ----------
NUM 40003.26 in 4 40003.26 4 10000,82
NUM 6006.16 in 9 6006.16 9 667,35
NUM 200 in 30 200 30 6,67
NUM 33 in 4 33 4 8,25
NUM 54545.01 in 700 54545.01 700 77,92
SQL>
即使你不熟悉的XMLQuery,它不应该是很难理解它是如何工作在这种特殊情况下。您可能需要单独选择REGEXP_REPLACE的结果,看到实际输入的XMLQuery。
然而,这种解决方案将窒息任何的下面示出为NUM ..... in ..... pieces
子句中的更大的数据集的额外的输入。
如果这种例外情况是可能的,你必须告诉我们如何各自的处理方式。请注意,.....
没有在所有需要的片段; with
test_data as (
select 1 id, 'blah bahwl NUM 40003.26 in 4 pieces. etc' str from dual union all
select 2 , 'bwh balshbh NUM 6006.16 in 9 pieces. etc' from dual union all
select 3 , 'badh sh alshbh NUM 200 in 30 pieces. etc' from dual union all
select 4 , 'bfda bdafl hxksw NUM 33 in 4 pieces. etc' from dual union all
select 5 , 'bl lshbh NUM 54545.01 in 700 pieces. etc' from dual
)
select id,
xmlquery(regexp_replace(str, '^.*?NUM(.*?)in(.*?)pieces.*$', '\1 div \2')
returning content).getNumberVal() as division_result
from test_data
;
ID DIVISION_RESULT
----- ---------------
1 10000.815000
2 667.351111
3 6.666667
4 8.250000
5 77.921443
缺少第二数目; WITH
具有所述第二数量等于0;和id = 6
有文字里应该有一个数字。
这说明了为什么,或许,如果你要处理这样的问题,您应该考虑增加两列,可能是虚拟的,如果你的Oracle版本是足够高,以保持公正所需号码 - 再处理可能出现的异常会变得容易得多。这也很明显,让您的数据模型更接近第一范式,它当前的模式,违背了明目张胆。
id = 7