1

我有一个查询将逗号视为字符串中的分隔符。我想取消最后一次出现。

示例:字符串:a、b、c、d 字符串:e、f、g、h、i、j

select regexp_substr(string, '[^,]+', -1, 1)
from dual;

应该返回:d 和 j

但错误消息说 -1 位置超出范围。

甲骨文文档:https ://docs.oracle.com/cd/E11882_01/olap.112/e23381/row_functions063.htm#OLAXS456

4

4 回答 4

3
SELECT regexp_substr(string, '[^,]*$') FROM t

测试

于 2017-02-17T15:14:30.927 回答
2

没有正则表达式的解决方案可能是:

select substr(string, instr( string, ',', -1)+1)
from yourTable

在这里,您使用instr来查找最后一次出现的 ','(如果有),然后使用 asubstr仅返回输入字符串的所需部分。

于 2017-02-17T15:18:52.840 回答
2

这里有几种方法可以做到:

WITH sample_data AS (SELECT 'a, b, c, d' str FROM dual UNION ALL
                     SELECT 'e, f, g, h, i, j' str FROM dual UNION ALL
                     SELECT 'e, f, g, h, i, jk' str FROM dual UNION ALL
                     SELECT 'e,f,g,h,i,jk' str FROM dual UNION ALL
                     SELECT 'e,f,g,h,i,' str FROM dual UNION ALL
                     SELECT 'e, f, g, h, i,' str FROM dual)
SELECT str,
       ltrim(SUBSTR(str, INSTR(str, ',', -1, 1) + 1)) last_item1,
       regexp_substr(str, '.*, ?([^,]*$)', 1, 1, NULL, 1) last_item3
FROM   sample_data;

STR               LAST_ITEM1        LAST_ITEM3
----------------- ----------------- -----------------
a, b, c, d        d                 d
e, f, g, h, i, j  j                 j
e, f, g, h, i, jk jk                jk
e,f,g,h,i,jk      jk                jk
e,f,g,h,i,                          
e, f, g, h, i,                      

关于哪个选项在您的系统中性能和/或可维护性最高,这是两个选项之间的折腾 - 您需要对此进行测试。

上面的 regexp_substr 解决方案检查任何字符的模式(换行符除外),后跟一个逗号,后跟一个空格(或不是),最后是直到字符串末尾的任何不是逗号的字符。然后我们输出第一个子表达式(它由模式的括号部分定义)。

我将 ltrim 包含在 substr/instr 项中,因为您说您的分隔符是逗号,但看起来可能是逗号+空格。

于 2017-02-17T15:32:23.343 回答
1

你在评论中问如果你想获得第二次出现怎么办?第 4 个参数是您要返回的元素。此格式处理 NULL 元素:

with tbl(str) as (
  select 'a, b, c, d' from dual union
  select 'e,,g,h,i,j' from dual
)
select regexp_substr(str, '(.*?)(,|$)', 1, 2, NULL, 1) element
from tbl; 
于 2017-02-17T16:33:52.417 回答