2013-06-18 5 views
1

Текущая таблица выглядит следующим образом:Обновление MySQL столбца таблицы последовательной цифры основаны на другой колонке

[id | section | order | thing] 
[1 | fruits | 0  | apple] 
[2 | fruits | 0  | banana] 
[3 | fruits | 0  | avocado] 
[4 | veggies | 0  | tomato] 
[5 | veggies | 0  | potato] 
[6 | veggies | 0  | spinach] 

Я задаюсь вопросом, как сделать таблицу выглядеть следующим образом:

[id | section | order | thing] 
[1 | fruits | 1  | apple] 
[2 | fruits | 2  | banana] 
[3 | fruits | 3  | avocado] 
[4 | veggies | 1  | tomato] 
[5 | veggies | 2  | potato] 
[6 | veggies | 3  | spinach] 

колонка «порядок» обновляется до последовательного номера, начиная с 1, на основе столбца «section» и столбца «id».

ответ

0

Вы не хотите делать это как UPDATE, так как это будет очень медленно.

Вместо этого сделайте это на INSERT. Вот простая однострочная строка INSERT, которая будет захватывать следующий номер заказа и вставляет в раздел «фрукты» запись под названием «киви».

INSERT INTO `table_name` (`section`, `order`, `thing`) 
SELECT 'fruits', MAX(`order`) + 1, 'kiwi' 
FROM `table_name` 
WHERE `section` = `fruits` 

EDIT: Вы также можете сделать это с помощью вставки триггера, например .:

DELIMITER $$ 
CREATE TRIGGER `trigger_name` 
BEFORE INSERT ON `table_name` 
FOR EACH ROW 
BEGIN 
    SET NEW.`order` = (SELECT MAX(`order`) + 1 FROM `table_name` WHERE `section` = NEW.`section`); 
END$$ 
DELIMITER ; 

Тогда вы можете просто вставить свои записи, как обычно, и они будут автоматически обновит значение order.

INSERT INTO `table_name` (`section`, `thing`) 
VALUES ('fruits', 'kiwi') 
+0

Я правильно понимаю, что это было бы полезно только для будущих вставок, а не для фиксации значений порядка в данных, находящихся в настоящее время внутри стол? –

+0

@JackieAD - Да, вышеупомянутые решения помешали бы вашим данным когда-либо получать в состоянии, которое нуждается в обновлении. Предполагая, что вы можете начать с новой пустой таблицы, это было бы идеальным решением. Или вы можете запустить свое обновление один раз и переключиться на это в будущем, чтобы предотвратить повторное обновление. –

+0

Но какая операция обновления? Это то, что я ищу для решения. –

0

Вместо того, чтобы хранить порядок, вы можете получить его:

SELECT t.id 
     ,t.section 
     ,@row_num := IF (@prev_section = t.section, @row_num+1, 1) AS ordering 
     ,t.thing 
     ,@prev_section := t.section 
    FROM myTable t 
     ,(SELECT @row_num := 1) x 
     ,(SELECT @prev_value := '') y 
    ORDER BY t.section, t.id 

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

1

Вы можете сделать это с помощью update с помощью join. Вторая таблица в соединении вычисляет порядок, который затем используется для обновления:

update t join 
     (select t.*, @rn := if(@prev = t.section, @rn + 1, 1) as rn 
     from t cross join (select @rn := 0, @prev := '') const 
     ) tsum 
     on t.id = tsum.id 
    set t.ordering = tsum.rn 
+0

Выглядит правильно, но я получил эту ошибку: # 1267 - Недопустимое сочетание сортировок (utf8_unicode_ci, IMPLICIT) и (utf8_general_ci, IMPLICIT) для операции '=' –

+0

@JackieAD. , , В вашей колонке не используется сортировка по умолчанию. Попробуйте изменить '@prev: = ''' на '@prev: = '' collate utf8_unicode_ci'. –

Смежные вопросы