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

(SQLite) Selecting # separated data as multiple rows

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

我的 table 看起来像这样: 拱门 id_a | str_ids

str_ids 字段包含连接外键如下:#id1#id2#id4#id7# (每行有不同数量的聚合 ID)

我对 SQLite 不是很熟悉,我很难找到对应的。我知道我必须这样做 "with recursive" 但我似乎无法掌握它。

我正在寻找的 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

在 SQLite 中,您可以使用递归通用 table 表达式来解决此问题。递归 CTE 从原始 table 中选择并将字符串拆分为子部分,主查询从中选择。

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:

    SQLite中没有
  • REGEXP_REPLACE,我用REPLACE

  • 代替了
  • 你需要一个 # 广告字符串的结尾才能工作(有两个 #` 也可以)

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