mysql - 在 MySQL 中使用单个语句更新具有递增值的列

标签 mysql sql

我有一个第三方应用程序,该应用程序已从早期版本迁移到当前版本,并且在迁移过程中,一个新列已添加到数据库中。该列表示外部测试用例标识符。表中有一个测试用例记录的唯一标识符,该标识符对用户是隐藏的。当创建测试用例的新版本时,一条新记录将添加到表中。显然有一个新的 ID,但外部标识符保持不变,因此最终用户认为这是相同的测试用例。不是我的模型,但足够公平。

在迁移过程中,添加了该列,现在所有测试用例的 id 看起来都为零。哎呀。好吧,几乎全部,因为已经通过 GUI 添加了一些新案例,并且它们的数量是正确的。启动其中一个测试用例实际上有第二个版本。我已修复该记录,使其具有有效的外部 ID。

这是我的表格相关部分的快照:

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/whatever 脚本来执行 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 显然无法胜任这项任务,如果有人能给我指出正确的 FM,我很乐意 RTM。

编辑:同事提出了以下解决方案

我的一位同事向我提供了解决方案,如果我自己这么说,那就太令人讨厌了。格式是我的,他把它写成了一长串。嘎。火焰消失了,但它确实起作用了。

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;

最佳答案

UPDATE tcversions SET tc_external_id = @id := IF( ISNULL( @id ), 1, @id + 1 )
    WHERE id = 0;

您可能希望将 1(@id 的起始值)替换为新插入中已有的最高 tc_external_id 之后的 1。

关于mysql - 在 MySQL 中使用单个语句更新具有递增值的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6944090/

相关文章:

php - 选择分层评论的查询太多

php - 数据库SELECT查询问题

java - 如何在java中正确编写带有if条件的sql查询

mysql - 如何在mysql中将2个表合并为1个表?

mysql - VB.NET 登录表单例份验证

php - Laravel:如何在子进程中通过 Eloquent 更新 MySQL?

php - MySQL 根据另一个查询的结果更新表

php - 如何更新我的查询以符合启用的 sql_mode=only_full_group_by?

mysql - 为什么带有子查询的 MySQL UPDATE 表现得很奇怪?

c# - MySql.Data.MySqlClient 命名空间与 System.Data.OracleClient 命名空间