(SQLite)选择#分隔的数据作为多行

时间:2019-01-16 22:21:17

标签: sql sqlite concatenation aggregation string-concatenation

我有一个表,其中在字段中包含简化的外键(分隔符#)。我想将数据转换为每个FK一行,以便可以对数据进行联接。

我的桌子看起来像这样: 阿奇 id_a | str_ids

str_ids字段包含一致的FK,如下所示:#id1#id2#id4#id7# (每行有不同数量的汇总ID)

我对SQLite并不是很熟悉,因此很难找到对应的对象。我知道我必须“递归地”执行此操作,但似乎无法理解。

我正在寻找的oracle等效项如下:

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 :(得分:0)

在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  |

View on DB Fiddle

NB2:

  • REGEXP_REPLACE在SQLite中不存在,我将其替换为REPLACE

  • 您需要在字符串的末尾插入#广告,这样才能正常工作(也可以使用两个#`)

  • 这不是一种非常有效的方法;如果您要处理的行很多,则可能无法很好地扩展。