Задать вопрос
@KTG

Как сделать отбор по вхождению части строки с разделителями в строку с разделителями?

Имеется таблица, назовем её "data_table":
ID | GROUPS
-----------------
01 | 'e;z'
02 | 'a;b'
03 | 'o;p'
04 | 'o;p;z'
05 | 'd;f'

И есть список значений,
a, b, c, d, z.
Который в запросе можно представить в виде:
select 'a;b;c;d;z' from dual;
или
select 'a','b','c','d','z' from dual;
По факту, список значений намного шире и может постоянно меняться. Количество строк в таблице то же великое множество.

Необходимо вернуть все строки из таблицы 'data_table', у которых в поле 'groups' встречается хотя бы одно значение из списка.
Т.е. к возврату, из данного примера, подлежат строки:
Result
----------
01 | 'e;z' -- т.к. в списке есть 'z'
02 | 'a;b' -- т.к. в списке есть 'a' и 'b'
04 | 'o;p;z' -- т.к. в списке есть 'z'
05 | 'b;f' -- т.к. в списке есть 'b'

Возможно ли подобное написать одним запросом (использовать PL/SQL стандартные функции допускается)?

UPD: вариант создать таблицу под список значений, где каждое значения - строка и сопоставлять по вхождению имеет право на жизнь, но не рассматривается.
Список значений можно вынести во временную таблицу конструкцией WITH, но пока не представляю как развернуть неопределенное количество столбцов в строки. Неопределенное, потому что мысль использовать unpivot или union с перечислением 100-1000 значений погружает в уныние.
  • Вопрос задан
  • 354 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
@KTG Автор вопроса
Буду использовать список значений в виде строки с разделителем.
Разобью её на табличные строки:
WITH
    val_list# AS
    (   
        SELECT 'a;b;c;d;z' AS lst FROM dual
    )

SELECT
      REGEXP_SUBSTR(lst, '[^;]+', 1, level) AS val
    FROM
        val_list#
    CONNECT BY level <= REGEXP_COUNT(lst, ';')+1

Дальше просто буду каждое значение из таблицы сопоставлять по вхождению в поле 'groups' таблицы 'data_table'.

Правда пока не понятно что лучше, в плане производительности.
Виртуально плодить строки в таблице 'data_table' разбивая так же на каждое найденное значение в поле 'groups'.
Или к каждой строке подключать таблицу значений.
Оба варианта пока смущают, а третий вариант еще не придумал...

Хотя было бы неплохо брать 1-ое значение, прогонять по таблице, при найденном совпадении неким образом помечать/отбрасывать строки, а уже по 2-му значению прогонять только оставшиеся и т.д.
Но как?

to be continued
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@d-stream
Готовые решения - не подаю, но...
Дубовый вариант - банальный like.
Нормальный - все-таки хранить данные правильно.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы