Разбить разделенные пробелом значения и отобразить их в исходный идентификатор в SQLite? - PullRequest
5 голосов
/ 17 января 2020

У меня есть таблица с именем personal_websessions, которая содержит данные в следующем формате:

 id_no | website_link 
 1     | google.com msn.com gmail.com 
 2     | stackoverflow.com reddit.com 
 3     | msn.com 

Вы можете создать эту таблицу с помощью следующих команд SQL:

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, 'stackoverflow.com reddit.com'), (3, 'msn.com ');

Я хотел бы разделить значения столбца website_link на пробелы '' , чтобы получить следующий результат таблицы:

id_no | website_link 
1     | google.com
1     | msn.com 
1     | gmail.com
2     | stackoverflow.com
2     | reddit.com
3     | msn.com

Я хотел бы разделить столбец website_link на один пробел для достижения этой цели - я пробовал разные методы, в том числе описанные здесь:

Но этот пример не помог так сильно, как для разделенных запятыми, а не разделенных пробелами

Я знаю, что есть способ сделать это с помощью sqlite, но я пока не понял этого! Любая помощь с благодарностью!

Спасибо - Гусфраба

Ответы [ 2 ]

1 голос
/ 17 января 2020

Рекурсивный 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;

Здесь - это db <> скрипка.

В этой конкретной версии все манипуляции со строками находятся в рекурсивной части CTE. Якорь просто устанавливает данные.

Использование обрезки делает запрос более устойчивым, если пробелы нерегулярны - например, у вас есть пробел в конце одного из текстовых значений.

Что касается lev, я почти всегда включаю это в рекурсивные CTE, чтобы я мог видеть глубину рекурсии, если я хочу.

Все это говорит о том, что это не очень хороший способ хранения данных. Вы должны использовать отдельную таблицу, структура которой больше похожа на набор результатов, который вы получаете - одна строка на идентификатор и уникальный веб-сайт.

1 голос
/ 17 января 2020

С рекурсивом 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

См. Демоверсию . Результаты:

| id_no | website_link      |
| ----- | ----------------- |
| 1     | google.com        |
| 1     | msn.com           |
| 1     | gmail.com         |
| 2     | stackoverflow.com |
| 2     | reddit.com        |
| 3     | msn.com           |
...