我有一个表,其中在字段中包含简化的外键(分隔符#)。我想将数据转换为每个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
答案 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 |
NB2:
REGEXP_REPLACE
在SQLite中不存在,我将其替换为REPLACE
您需要在字符串的末尾插入#
广告,这样才能正常工作(也可以使用两个#`)
这不是一种非常有效的方法;如果您要处理的行很多,则可能无法很好地扩展。