在Oracle SQL中返回字符串中的文本

时间:2017-08-18 14:42:11

标签: sql string oracle

我在表格的一列中有字符串数据,其中包含货币金额。

E.G。该列可能包含以下内容: “戴夫曾向彩票集团支付50英镑” “该基金2017年的总投资回报率达到150,964.39英镑”

如何搜索“£”符号的出现次数,然后返回之后出现的数字?

由于

1 个答案:

答案 0 :(得分:1)

这是一种方法。搜索表达式有点复杂,因为它必须允许千位分隔符和小数点,所有这些都是可选的。它假设“西方”使用了数千个分隔符 - 例如,它必须稍微修改以允许Lakh(印度)符号。当没有井号时,或者如果有一个井号不紧跟一个至少一个数字,它将产生NULL。 (因此,如果您允许使用£.60而不是£0.60,则必须略微修改。)如果需要,您还可以捕获金额(没有货币符号) - 这也是一个小小的修改使用REGEXP_SUBSTR(使用捕获组)。

如果每个输入行可能有多个金额,则需要进行最大的更改。

with
     inputs ( str ) as (
       select 'Dave once paid £50.00 to a lottery syndicate.' from dual union all
       select 'Total Returns in 2017 came to £150,964.39.'    from dual
     )
-- End of simulated inputs (for testing purposes only, not part of the solution).
-- Use your actual table and column names in the SQL query below.
select str, regexp_substr(str, '£\d{1,3}(,?\d{3})*(\.\d+)?') as amount
from   inputs
;

STR                                            AMOUNT
---------------------------------------------  -----------
Dave once paid £50.00 to a lottery syndicate.  £50.00
Total Returns in 2017 came to £150,964.39.     £150,964.39

修改

在下面的评论中,OP询问如何仅获取金额,而不使用货币符号。最简单的方法是直接在REGEXP_SUBSTR()函数中使用捕获组。下面的版本使用函数的所有六个参数:如前一个是输入字符串,第二个是搜索模式。第三个和第四个是起始位置和发生(对于这个问题,两者总是等于1)。第五个,NULL,用于我们不需要的一些特殊选项。第六个参数是相关的:1表示返回第一个捕获组,即包含在第一对匹配括号中的搜索模式的一部分(从左到右计数)。注意搜索模式中的另外一对括号,以将数量与井号符号隔离:

regexp_substr(str, '£(\d{1,3}(,?\d{3})*(\.\d+)?)', 1, 1, null, 1)

编辑#2

要提取NUMBER数据类型中的金额,不必删除井号; TO_NUMBER()函数可以处理它。相反,使用正确的格式模型和显式货币符号,必须在TO_NUMBER()内包装只是英镑符号后跟金额的子字符串:

to_number(regexp_substr(str, '£\d{1,3}(,?\d{3})*(\.\d+)?'), 
               'L999,999,999,999,999.000000', 'nls_currency=£')

请确保在小数点右侧包含足够的数字以容纳所有可能的金额。 (格式模型中的数字过多绝不是问题。)