选择字符串中包含的所有子字符串

时间:2018-06-29 14:30:43

标签: sql oracle

我有一个字符串,其中包含多个由定界符分隔的子字符串。  substr1#substr2#substr3...#substrN

我想查询列中也包含此字符串的所有值。

到目前为止,我有:

SELECT substring_col
FROM table
WHERE id IN SUBSTR(str_to_search,INSTR(str_to_search,substring_col),INSTR(str_to_search,'#',INSTR(str_to_search,substring_col))-1)

但是,这仅返回找到的第一个子字符串。如何使它返回找到的所有子字符串?

3 个答案:

答案 0 :(得分:1)

糟糕的数据格式,并且有很多原因需要更改。

但是,有时我们会陷于别人真正非常糟糕的格式。一种方法是使用like

where '#' || listcol || '#' like '%#' || id || '#%'

答案 1 :(得分:1)

恐怕形式为'[^#]+'的正则表达式不能处理NULL元素。不幸的是,它是解析定界字符串时最常见的答案。有关证明和详细信息,请参见帖子:https://stackoverflow.com/a/31464699/2543416。使用它,带有NULL元素2的数据集将得到以下结果集:

SUBS
-----------
substr1
substr3
substrN
<NULL here>

SQL>

请改用建立在Littlefoot的答案上的这种形式(注意元素2为NULL):

with test as (select 'substr1##substr3#substrN' col from dual)
    select regexp_substr(col, '(.*?)(#|$)', 1, level, NULL, 1) subs
    from test
    connect by regexp_substr(col, '(.*?)(#|$)', 1, level) is not null;

SUBS
-----------
substr1

substr3
substrN

SQL>

此处保留了第二个元素的NULL,其余值位于正确的位置。

对于您而言,您可能并不关心值的位置,而只是在列表中。但是,出于可重用性(和准确性)的考虑,您可以将其转换为一个函数,在其中传递字符串,定界符和要获取的值,并使其返回位置。非零表示它在列表中,并且如果需要的话,您也可以保留它的位置。只是一个想法。

答案 2 :(得分:0)

如果我对您的理解正确,则可能需要拆分长定界字符串

方法如下:

addCost() {
  $(document).ready(() => {
    (<any>$('input')).iCheck({
      checkboxClass: 'icheckbox_square-blue',
      radioClass: 'iradio_minimal-grey'
    });
    $('#not2bpaid').on('ifChecked', () => {
      this.not2bpaid_tosend = "N";
    });
  });
}

这意味着您的查询可能如下所示:

SQL> with test as (select 'substr1#substr2#substr3#substrN' col from dual)
  2  select regexp_substr(col, '[^#]+', 1, level) subs
  3  from test
  4  connect by level <= regexp_count(col, '#') + 1;

SUBS
--------------------------------------------------------------------------------
substr1
substr2
substr3
substrN

SQL>

定界字符串可能是一个参数;我想您可以用这种方式重写上面的代码。