я хочу разбить данные строки в базе данных и сохранить в другую таблицу в разных строках - PullRequest
1 голос
/ 29 марта 2020

У меня есть данные, подобные этому жанру =

Animation / Family / Fantasy / Musical / Romance

Я хочу сохранить как =

Animation
Family
Fantasy
Musical
Romance

В разных строках новой таблицы

Ответы [ 2 ]

1 голос
/ 29 марта 2020

Разделение строки с разделителями болезненно в MySQL - и часто указывает на проблему с дизайном. Было бы лучше сохранить каждое значение в отдельной таблице.

Тем не менее, вот решение для разбора строки с использованием таблицы чисел:

select substring_index(substring_index (genre, ' / ', x.n), ' / ', -1) genre1
from t
inner join (
    select 1 n 
    union all select 2 
    union all select 3 
    union all select 4
    union all select 5
) x on x.n <= 1 + length(genre) - length(replace(genre, '/', ''))

Это может анализировать до 5 значений на строку; чтобы обрабатывать больше, вам нужно добавить больше union all подзапросов.


В самых последних версиях синтаксис values может использоваться для сокращения запроса:

select substring_index(substring_index (genre, ' / ', x.n), ' / ', -1) genre1
from t
inner join (values row(1), row(2), row(3), row(4), row(5)) x(n) 
    on x.n <= 1 + length(genre) - length(replace(genre, '/', ''))

Наконец - для удовольствия: в MySQL 8.0 это можно сделать с помощью рекурсивного запроса, который является более гибким (хотя, возможно, и менее эффективным):

with recursive cte as (
    select 
        genre, 
        substring_index(substring_index (genre, ' / ', 1), ' / ', -1) genre1, 
        1 n,
        1 + length(genre) - length(replace(genre, '/', '')) n_max
    from t
    union all
    select 
        genre, 
        substring_index(substring_index (genre, ' / ', n + 1), ' / ', -1),
        n + 1,
        n_max
    from cte
    where n < n_max
)
select genre1 from cte

Демонстрация на DB Fiddle :

| genre1    |
| :-------- |
| Animation |
| Family    |
| Fantasy   |
| Musical   |
| Romance   |
0 голосов
/ 29 марта 2020

Вот одно из решений:

INSERT INTO NewTable (genre)
 SELECT TRIM(SUBSTRING_INDEX(genres, '/', 1)) FROM OldTable
 UNION
 SELECT TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(genres, '/', 2), '/', -1)) FROM OldTable
 UNION
 SELECT TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(genres, '/', 3), '/', -1)) FROM OldTable
 UNION
 SELECT TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(genres, '/', 4), '/', -1)) FROM OldTable
 UNION
 SELECT TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(genres, '/', 5), '/', -1)) FROM OldTable;

Подробнее о SUBSTRING_INDEX () и TRIM () .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...