在串并除以搜索子

问题描述 投票:1回答:3

我有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 

等等

任何帮助赞赏和蔼

sql regex oracle oracle11g oracle10g
3个回答
1
投票

您可以使用qazxsw POI,qazxsw POI与qazxsw POI /如下regexp_substr贡献

regexp_replace

l


0
投票

此选项选择输入字符串的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

0
投票

如果你能保证所有的(我的意思是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
© www.soinside.com 2019 - 2024. All rights reserved.