Выберите все подстроки, которые содержатся в строке - PullRequest
0 голосов
/ 29 июня 2018

У меня есть строка, которая содержит несколько подстрок, разделенных символом разделителя. 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 голосов
/ 29 июня 2018

Если я вас правильно понял, разделение этой строки с разделителями может быть тем, что вы ищете.

Вот как:

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>

Это означает, что ваш запрос может выглядеть так:

SELECT substring_col
FROM table
WHERE id IN (SELECT regexp_substr('substr1#substr2#substr3#substrN', '[^#]+', 1, level) subs
             FROM dual
             CONNECT BY level <= regexp_count('substr1#substr2#substr3#substrN', '#') + 1
            );

Строка с разделителями, вероятно, является параметром; Я думаю, что вы можете переписать приведенный выше код таким образом.

0 голосов
/ 29 июня 2018

Боюсь, что регулярное выражение формы '[^#]+' не обрабатывает 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 голосов
/ 29 июня 2018

Ужасный формат данных, и есть много причин, по которым вы должны изменить его.

Но иногда мы застряли в действительно, очень плохих форматах других людей. Один метод заключается в использовании like:

where '#' || listcol || '#' like '%#' || id || '#%'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...