SQLite: разложить строку в столбец


Автор: Artix (user.su)

Задача:

Есть некоторая строка с полями фиксированной длины, в нашем случае - 
просто строка символов. Необходимо вывести символы в один столбец.

Комментарий:

По смыслу эта задача похожа на реализацию функции STR_SPLIT(str, delimiter),
которая разбивает строку через определенный разделитель, но немного проще - 
потому что все поля фиксированы. К примеру, строка может содержать коды стран

'RUENBYKZAMUA' и так далее.


Решение:

Сделать такой финт легко с помощью рекурсивного выражения CTE, которое 
возвращает индекс очередной позиции.

WITH RECURSIVE IDX (N) AS (
    SELECT 1 AS N FROM RDB$DATABASE
        WHERE CHAR_LENGTH('MOSCOW')>0
    UNION ALL
    SELECT N+1 FROM IDX
        WHERE N<CHAR_LENGTH('MOSCOW')
)
SELECT SUBSTRING('MOSCOW' FROM N FOR 1) FROM IDX


Комментарий:

Аналогично можно посчитать число необходимых символов (пробелов) в строке или отфильтровать какие-то символы


Расширение:

Если поля не фиксированы, а разделены неким разделителем (delimiter), то запрос тоже можно вывести через
выражения CTE, однако в этом случае выражение должно возвращать две позиции: начала и конца вырезаемого отрезка

WITH RECURSIVE T (P1,P2) AS (
    SELECT 1 as P1, 
       IIF(POSITION(';','1;02;003;0004;00005;')>0,
            POSITION(';','1;02;003;0004;00005;'),
            CHAR_LENGTH('1;02;003;0004;00005;')) as P2 FROM RDB$DATABASE
    UNION ALL
    SELECT P2+CHAR_LENGTH(';'), 
       IIF(POSITION(';','1;02;003;0004;00005;',P2+1)>0,
            POSITION(';','1;02;003;0004;00005;',P2+1),
            CHAR_LENGTH('1;02;003;0004;00005;')+1) FROM T
    WHERE P1<=P2 AND P2<=CHAR_LENGTH('1;02;003;0004;00005;')
)
SELECT P1, P2, SUBSTRING('1;02;003;0004;00005;' FROM P1 FOR P2-P1) FROM T

#