Обновите столбец с увеличением значения, используя один оператор в MySQL - PullRequest
2 голосов
/ 04 августа 2011

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

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

Вот снимок соответствующего бита моей таблицы:

mysql> select id, version, tc_external_id from tcversions order by id limit 5;
+------+---------+----------------+
| id   | version | tc_external_id |
+------+---------+----------------+
| 9454 |       1 |              0 |
| 9455 |       1 |              5 |
| 9456 |       1 |              0 |
| 9457 |       1 |              0 |
| 9458 |       1 |              0 |
+------+---------+----------------+
5 rows in set (0.33 sec)

Для тех из вас, кто знаком с базой данных, даэто TestLink 1.9.3.Это перенесенная база данных из модифицированной системы 1.7.4, которую мы унаследовали.

Я ищу оператор MySQL UPDATE, который позволил бы мне обновить tc_external_id так, чтобы каждая запись получала монотонно увеличивающееся число без необходимости прибегать кна написание отдельного скрипта bash / perl / what, который выполняет N обновлений.Таким образом, результат будет выглядеть примерно так:

mysql> select id, version, tc_external_id from tcversions order by id limit 5;
+------+---------+----------------+
| id   | version | tc_external_id |
+------+---------+----------------+
| 9454 |       1 |              6 |
| 9455 |       1 |              5 |
| 9456 |       1 |              7 |
| 9457 |       1 |              8 |
| 9458 |       1 |              9 |
+------+---------+----------------+
5 rows in set (0.33 sec)

Возможно ли это?Мой SQL foo, очевидно, не соответствует задаче, и я рад RTM, если кто-то может указать мне правильный FM.

Редактировать: Сотрудник придумал следующее решение

Мой коллега предоставил мне решение, и это довольно неприятно, если я сам так скажу.Форматирование мое, он сделал это одной длинной строкой.Гах.Пламя исчезло, но это сработало.

REPLACE INTO tcversions 
  SELECT @r := id as id, 
         @r1 := version as version, 
         @r2 := summary as summary, 
         @r3 := importance as importance, 
         @r4 := author_id as author_id, 
         @r5 := creation_ts as creation_ts,
         @r6 := updater_id as updater_id, 
         @r7 := modification_ts as modification_id, 
         @r8 := active as active, 
         @r9 := is_open as is_open, 
         @r10 := execution_type as execution_type, 
         @c := @c + 1 as tc_external_id, 
         @r12 := layout as layout, 
         @r13 := status as status, 
         @r14 := preconditions as preconditions 
  FROM 
    (SELECT @r := '', 
            @r1 := '', 
            @r2 := '', 
            @r3 := '', 
            @r4 := '', 
            @r5 := '', 
            @r6 := '', 
            @r7 := '', 
            @r8 :='', 
            @r9 := '', 
            @r10 := '', 
            @r11 := '', 
            @r12 := '', 
            @r13 := '', 
            @r14 := '',  
            @c := max(tcversions.tc_external_id) from tcversions ) rc, 
    (SELECT id,
            version, 
            summary, 
            importance, 
            author_id, 
            creation_ts, 
            updater_id, 
            modification_ts, 
            active, 
            is_open, 
            execution_type, 
            tc_external_id, 
            layout, 
            status, 
            preconditions 
     FROM tcversions  WHERE tc_external_id = 0  ORDER BY id) k;

Ответы [ 3 ]

2 голосов
/ 04 августа 2011
UPDATE tcversions SET tc_external_id = @id := IF( ISNULL( @id ), 1, @id + 1 )
    WHERE id = 0;

вы можете заменить это 1 (начальное значение @id) на одно после наибольшего tc_external_id, которое у вас уже есть из новых вставок.

1 голос
/ 21 марта 2014

Для справки

Я нашел ответ здесь :

SET @id = 5;
UPDATE tcversions
  SET tc_external_id = (SELECT @id := @id + 1)
  WHERE tc_external_id=0
  ORDER BY id;
0 голосов
/ 04 августа 2011

Это как-то связано с запросом top10.Эскиз с использованием SQlite:

sqlite> select a.id, a.version, count(*)
        from tcversions a, tcversions b
        where a.id >= b.id
        group by a.id;
9454|1|1
9455|1|2
9456|1|3
9457|1|4

Вопрос в том, как обновить таблицу сейчас; -)

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