拆分 space 分隔值并将它们映射到 SQLite 中的原始 ID?
Split space separated values and map them to original ID in SQLite?
我有一个名为 personal_websessions
的 table,它包含以下格式的数据:
id_no | website_link
1 | google.com msn.com gmail.com
2 | whosebug.com reddit.com
3 | msn.com
您可以使用以下 SQL 命令创建此 table:
CREATE TABLE personal_websessions(id_no INTEGER PRIMARY KEY, website_link TEXT);
INSERT INTO personal_websessions VALUES(1, 'google.com msn.com gmail.com'), (2, 'whosebug.com reddit.com'), (3, 'msn.com ');
我想将 website_link 列的值拆分为 spaces ' ' 以获得以下 table 结果:
id_no | website_link
1 | google.com
1 | msn.com
1 | gmail.com
2 | whosebug.com
2 | reddit.com
3 | msn.com
我想将 website_link 列拆分为 单个 space 以实现此目的 - 我尝试了不同的方法,包括此处概述的方法:
我知道有一种方法可以使用 sqlite 来执行此操作,但我还没有弄明白!任何帮助是极大的赞赏!
谢谢 - Goosfraba
用递归CTE
:
with recursive cte as (
select id_no, trim(website_link) || ' ' website_link,
substr(
website_link,
1,
case
when website_link like '% %' then instr(website_link, ' ') - 1
else website_link
end
) link
from personal_websessions
union all
select c.id_no, substr(c.website_link, length(c.link) + 2),
substr(
substr(c.website_link, length(c.link) + 2),
1,
instr(substr(c.website_link, length(c.link) + 2), ' ') - 1
) link
from cte c
where substr(c.website_link, length(c.link) + 2) like '% %'
)
select id_no, link website_link
from cte
order by id_no
参见demo。
结果:
| id_no | website_link |
| ----- | ----------------- |
| 1 | google.com |
| 1 | msn.com |
| 1 | gmail.com |
| 2 | whosebug.com |
| 2 | reddit.com |
| 3 | msn.com |
递归 CTE 是 SQLite 中最好的方法。我更喜欢这样的版本:
with cte(id_no, website_link, rest, lev) as (
select pw.id_no, NULL as website_link, trim(pw.website_link) || ' ' as rest, 1 as lev
from personal_websessions pw
union all
select cte.id_no,
trim(substr(cte.rest, 1, instr(cte.rest, ' '))),
substr(cte.rest, instr(cte.rest, ' ') + 1),
lev + 1
from cte
where rest <> ''
)
select id_no, website_link
from cte
where website_link <> ''
order by id_no;
Here 是一个 db<>fiddle.
在这个特定版本中,所有字符串操作都在 CTE 的递归部分。主播只是设置数据。
如果 space 是不规则的,使用 trim 可以使查询更健壮——例如,您在其中一个文本值的末尾有一个 space .
至于 lev
,我几乎总是将其包含在递归 CTE 中,这样我可以根据需要查看递归的深度。
综上所述,这不是存储数据的好方法。您应该使用一个单独的 table,其结构更像您得到的结果集——每个 id 和唯一网站一行。
我有一个名为 personal_websessions
的 table,它包含以下格式的数据:
id_no | website_link
1 | google.com msn.com gmail.com
2 | whosebug.com reddit.com
3 | msn.com
您可以使用以下 SQL 命令创建此 table:
CREATE TABLE personal_websessions(id_no INTEGER PRIMARY KEY, website_link TEXT);
INSERT INTO personal_websessions VALUES(1, 'google.com msn.com gmail.com'), (2, 'whosebug.com reddit.com'), (3, 'msn.com ');
我想将 website_link 列的值拆分为 spaces ' ' 以获得以下 table 结果:
id_no | website_link
1 | google.com
1 | msn.com
1 | gmail.com
2 | whosebug.com
2 | reddit.com
3 | msn.com
我想将 website_link 列拆分为 单个 space 以实现此目的 - 我尝试了不同的方法,包括此处概述的方法:
我知道有一种方法可以使用 sqlite 来执行此操作,但我还没有弄明白!任何帮助是极大的赞赏!
谢谢 - Goosfraba
用递归CTE
:
with recursive cte as (
select id_no, trim(website_link) || ' ' website_link,
substr(
website_link,
1,
case
when website_link like '% %' then instr(website_link, ' ') - 1
else website_link
end
) link
from personal_websessions
union all
select c.id_no, substr(c.website_link, length(c.link) + 2),
substr(
substr(c.website_link, length(c.link) + 2),
1,
instr(substr(c.website_link, length(c.link) + 2), ' ') - 1
) link
from cte c
where substr(c.website_link, length(c.link) + 2) like '% %'
)
select id_no, link website_link
from cte
order by id_no
参见demo。
结果:
| id_no | website_link |
| ----- | ----------------- |
| 1 | google.com |
| 1 | msn.com |
| 1 | gmail.com |
| 2 | whosebug.com |
| 2 | reddit.com |
| 3 | msn.com |
递归 CTE 是 SQLite 中最好的方法。我更喜欢这样的版本:
with cte(id_no, website_link, rest, lev) as (
select pw.id_no, NULL as website_link, trim(pw.website_link) || ' ' as rest, 1 as lev
from personal_websessions pw
union all
select cte.id_no,
trim(substr(cte.rest, 1, instr(cte.rest, ' '))),
substr(cte.rest, instr(cte.rest, ' ') + 1),
lev + 1
from cte
where rest <> ''
)
select id_no, website_link
from cte
where website_link <> ''
order by id_no;
Here 是一个 db<>fiddle.
在这个特定版本中,所有字符串操作都在 CTE 的递归部分。主播只是设置数据。
如果 space 是不规则的,使用 trim 可以使查询更健壮——例如,您在其中一个文本值的末尾有一个 space .
至于 lev
,我几乎总是将其包含在递归 CTE 中,这样我可以根据需要查看递归的深度。
综上所述,这不是存储数据的好方法。您应该使用一个单独的 table,其结构更像您得到的结果集——每个 id 和唯一网站一行。