(SQLite) Выбор # разделенных данных в виде нескольких строк - PullRequest
0 голосов
/ 17 января 2019

У меня есть таблица, которая содержит конкатенацию внешних ключей (разделитель #) в поле. Я хочу преобразовать данные в одну строку для каждого FK, чтобы я мог выполнить объединение данных.

Мой стол выглядит так: ARCHE id_a | str_ids

Поле str_ids содержит конкатенацию FK следующим образом: # id1 # id2 # id4 # id7 # (Для каждой строки имеется разное количество агрегированных идентификаторов)

Я не очень знаком с SQLite, и у меня проблемы с поиском аналога. Я понял, что должен делать это "с помощью рекурсии", но, похоже, я не могу освоить это.

Оракул, эквивалентный тому, что я ищу, выглядит следующим образом:

select 
    id_a
    ,trim(regexp_substr(str_ids, '[^#]+', 1, LEVEL)) as id_b          
from arche
connect by trim(regexp_substr(str_ids, '[^#]+', 1, LEVEL)) IS NOT NULL

1 Ответ

0 голосов
/ 17 января 2019

В SQLite вы можете использовать рекурсивное общее табличное выражение для решения этой проблемы. Рекурсивный CTE выбирает из исходной таблицы и разбивает строки на части, которые выбирает основной запрос.

WITH RECURSIVE cte(id, val, etc) AS(
    SELECT id_a, '', str_ids FROM arche
    UNION ALL
    SELECT 
        id
        , SUBSTR(etc, 0, INSTR(etc, '#'))
        , SUBSTR(etc, INSTR(etc, '#')+1)
    FROM cte
    WHERE etc <> ''
)
SELECT id AS id_a, REPLACE(val, 'id', '') AS id_b
FROM cte
WHERE val <> ''
ORDER BY id, val

Вот пример:

Схема (SQLite v3.26)


Запрос № 1

WITH RECURSIVE cte(id, val, etc) AS(
    SELECT 1, '', '#id1#id2#id4#id7#'
    UNION ALL
    SELECT 
        id
        , SUBSTR(etc, 0, INSTR(etc, '#'))
        , SUBSTR(etc, INSTR(etc, '#')+1)
    FROM cte
    WHERE etc <> ''
)
SELECT id AS id_a, val AS id_b
FROM cte
WHERE val <> ''
ORDER BY id, val;
| id_a | id_b |
| ---- | ---- |
| 1    | id1  |
| 1    | id2  |
| 1    | id4  |
| 1    | id7  |

Просмотр на БД Fiddle

NB2:

  • REGEXP_REPLACE не существует в SQLite, я заменил его на REPLACE

  • вам нужно # объявление в конце строки, чтобы это работало (наличие двух # `тоже нормально)

  • это не очень эффективный подход; если вам нужно обработать много строк, это может плохо масштабироваться.

...