Заменить часть строки другой строкой, не всегда являющейся одной и той же исходной строкой?

0

У меня есть следующая таблица (я знаю, что эти строки, разделенные запятой, ошибочны, но я просто выполняю эту работу):

Плоды стола:

Изображение 174551

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

Поэтому я пытаюсь сделать REPLACE следующим образом:

UPDATE fruits SET fruit_data=REPLACE(fruit_data,',greenPear','');    --that comma needs to
UPDATE fruits SET fruit_data=REPLACE(fruit_data,'greenPear,','');    --be deleted too
UPDATE fruits SET fruit_data=REPLACE(fruit_data,'greenPear','');
DELETE FROM fruits WHERE fruit_data = '';

И это работает, но только для "зеленых груш", и мне нужно удалить "все" груши, а не только зеленые. Есть двадцать разных цветов, и мне нужно знать, есть ли способ не повторять в двадцать раз вышеприведенный код.

  • 0
    Вы, вероятно, можете сделать это в MySQL 8.0, который, я считаю, расширил возможности preg_match. В противном случае вы застряли. Вы могли бы с большей пользой потратить время на исправление базы данных.
  • 0
    Можете ли вы предоставить вывод "SHOW CREATE TABLE fruits", или у вас есть какие-либо столбцы первичного ключа в таблице?
Показать ещё 2 комментария
Теги:

1 ответ

1
Лучший ответ

Если у вас есть первичный ключ в таблице, то приведенный ниже SQL действительно поможет вам:

Ваш SQL должен понравиться в соответствии с моими лучшими попытками:

update fruits f
left join (
select id,group_concat(fruit) new_fruit_data from(
SELECT id,SUBSTRING_INDEX(SUBSTRING_INDEX(t.fruit_data, ',', x.cifre), ',', -1) AS fruit
,count(1)
FROM (
SELECT id,fruit_data FROM fruits) t
INNER JOIN
(
    SELECT 1 + a.i + b.i * 10  cifre, b.i + a.i * 10  sute
    FROM (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) a
    CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) b
) x
ON (length(fruit_data)-length(replace(fruit_data,',',''))+1) >= x.cifre
group by id,SUBSTRING_INDEX(SUBSTRING_INDEX(t.fruit_data, ',', x.cifre), ',', -1)) k
where fruit not rlike 'pear'
group by id) n
on f.id = n.id
set f.fruit_data = n.new_fruit_data;

Объяснение в деталях:

Настройка таблицы:

create table fruits(id int,fruit_data varchar(500));
insert into fruits values(1,'greenApple,greePear,redApple');
insert into fruits values(2,'greePear');
insert into fruits values(3,'redApple,orangePear');
insert into fruits values(4,'greenApple,redApple');
insert into fruits values(5,'yellowPear,greenApple,greenPear');

Данные базовой таблицы.

mysql> select * from fruits;
+------+---------------------------------+
| id   | fruit_data                      |
+------+---------------------------------+
|    1 | greenApple,greePear,redApple    |
|    2 | greePear                        |
|    3 | redApple,orangePear             |
|    4 | greenApple,redApple             |
|    5 | yellowPear,greenApple,greenPear |
+------+---------------------------------+
5 rows in set (0.00 sec)

Вот обходное решение и ваше решение:

mysql> update fruits f
    -> join (
    -> select id,group_concat(fruit) new_fruit_data from(
    -> SELECT id,SUBSTRING_INDEX(SUBSTRING_INDEX(t.fruit_data, ',', x.cifre), ',', -1) AS fruit
    -> ,count(1)
    -> FROM (
    -> SELECT id,fruit_data FROM fruits) t
    -> INNER JOIN
    -> (
    ->     SELECT 1 + a.i + b.i * 10  cifre, b.i + a.i * 10  sute
    ->     FROM (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) a
    ->     CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) b
    -> ) x
    -> ON (length(fruit_data)-length(replace(fruit_data,',',''))+1) >= x.cifre
    -> group by id,SUBSTRING_INDEX(SUBSTRING_INDEX(t.fruit_data, ',', x.cifre), ',', -1)) k
    -> where fruit not rlike 'pear'
    -> group by id) n
    -> on f.id = n.id
    -> set f.fruit_data = n.new_fruit_data;
Query OK, 3 rows affected (0.05 sec)
Rows matched: 4  Changed: 3  Warnings: 0

Результат после обновления:

mysql> select * from fruits;
+------+---------------------+
| id   | fruit_data          |
+------+---------------------+
|    1 | greenApple,redApple |
|    2 | NULL                |
|    3 | redApple            |
|    4 | greenApple,redApple |
|    5 | greenApple          |
+------+---------------------+
5 rows in set (0.00 sec)
  • 0
    Здесь я создал столбец с именем ID для уникальных значений в таблице, замените столбец ID на имя столбца первичного ключа
  • 0
    Я добавил «LEFT» с «JOIN», так что ID-2 будет обновляться с нуля
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню