UPDATE SET столбец с разными значениями в строке - PullRequest
3 голосов
/ 19 сентября 2019

Если у меня есть таблица my_table, подобная этой:

| id | val1 | val2|
| 1  | foo1 | bar |
| 2  | foo2 | baz |
| 3  | foo3 | bam |

И у меня есть жестко запрограммированный список значений, разделенных запятыми, который я сгенерировал программно: spam, eggs, ham.

Я хочу вставить свои значения в столбец val1.Я воображаю что-то вроде этого:

UPDATE my_table SET val1 = SELECT * FROM (VALUES ('spam'),('eggs'),('ham'))

Но это дает мне синтаксическую ошибку (MySQL 5.6.44)

Конечный результат должен выглядеть так:

| id | val1 | val2|
| 1  | spam | bar |
| 2  | eggs | baz |
| 3  | ham  | bam |

Ответы [ 2 ]

6 голосов
/ 19 сентября 2019
DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,val1 VARCHAR(12) NOT NULL
,val2 VARCHAR(12) NOT NULL
);

INSERT INTO my_table VALUES
(1,'foo1','bar'),
(2,'foo2','baz'),
(3,'foo3','bam');

UPDATE my_table SET val1 = SUBSTRING_INDEX(SUBSTRING_INDEX('spam,eggs,ham',',',id),',',-1);

SELECT * FROM my_table;
+----+------+------+
| id | val1 | val2 |
+----+------+------+
|  1 | spam | bar  |
|  2 | eggs | baz  |
|  3 | ham  | bam  |
+----+------+------+
5 голосов
/ 22 сентября 2019

@ Strawberry 's answer действительно образцово;но что, если значения id не являются непрерывными.

Например, значения id равны 2, 5, 6.В этом случае мы можем эмулировать непрерывную new_id, используя Row_Number() функциональность в MariaDB 10.2+ / MySQL 8+.Я также заметил, что у вашей входной строки, разделенной запятыми, есть пробелы после запятой.Чтобы справиться с этим (переменная величина интервала), мы можем использовать функцию Trim() после операции подстроки.Опираясь на превосходный ответ @ Strawberry :

Схема (MySQL v8.0) - Вид на БД Fiddle

CREATE TABLE your_table_name
(id INT UNSIGNED PRIMARY KEY
,val1 VARCHAR(12) NOT NULL
,val2 VARCHAR(12) NOT NULL
);

INSERT INTO your_table_name VALUES
(2,'foo1','bar'),
(5,'foo2','baz'),
(6,'foo3','bam');

Запрос на обновление

UPDATE your_table_name t1
       JOIN (SELECT Row_number()
                      OVER (
                        ORDER BY id) AS new_id,
                    id
             FROM   your_table_name) t2
         ON t2.id = t1.id
SET    val1 =
Trim(Substring_index(Substring_index('spam, eggs,  ham', ',', t2.new_id), ',', -1));

Проверка данных

SELECT * FROM your_table_name;

| id  | val1 | val2 |
| --- | ---- | ---- |
| 2   | spam | bar  |
| 5   | eggs | baz  |
| 6   | ham  | bam  |

--

В старых версиях MySQL / MariaDB оконные функции недоступны.В этом случае мы можем использовать определяемые пользователем переменные для эмуляции new_id:

Схема (MySQL v5.7) - Просмотр в БД Fiddle

CREATE TABLE your_table_name
(id INT UNSIGNED PRIMARY KEY
,val1 VARCHAR(12) NOT NULL
,val2 VARCHAR(12) NOT NULL
);

INSERT INTO your_table_name VALUES
(2,'foo1','bar'),
(5,'foo2','baz'),
(6,'foo3','bam');

Запрос на обновление

UPDATE your_table_name t1
       JOIN (SELECT @rn := @rn + 1 AS new_id, 
                    id 
             FROM   your_table_name 
             CROSS JOIN (SELECT @rn := 0) vars
             ORDER BY id) t2
         ON t2.id = t1.id
SET    val1 =
Trim(Substring_index(Substring_index('spam, eggs,  ham', ',', t2.new_id), ',', -1));

Проверка данных

SELECT * FROM your_table_name;

| id  | val1 | val2 |
| --- | ---- | ---- |
| 2   | spam | bar  |
| 5   | eggs | baz  |
| 6   | ham  | bam  |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...