【问题标题】:Using code to increment values in a column使用代码增加列中的值
【发布时间】:2020-12-05 15:15:42
【问题描述】:

我正在尝试使用一个简单的代码来仅增加表的“chat_id”列中的值。

对于表 lz_chat_archive_dup1,“chat_id”列具有空字符串(无值)。这是表格的部分摘录:

mysql> select chat_id, fullname from lz_chat_archive_dup1 LIMIT 5;
+---------+--------------+
| chat_id | fullname     |
+---------+--------------+
|         | Yw           |
|         | Shah         |
|         | Sunny Duhel  |
|         | Leong Zi Yin |
|         | Mohd Nasir   |
+---------+--------------+
5 rows in set (0.00 sec)

我尝试像这样为名称“Yw”插入一个值,它成功了:

mysql> UPDATE lz_chat_archive_dup1 SET chat_id = '383933' where fullname = 'Yw';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

所以现在表格是这样的:

mysql> select chat_id, fullname from lz_chat_archive_dup1 LIMIT 5;
+---------+--------------+
| chat_id | fullname     |
+---------+--------------+
| 383933  | Yw           |
|         | Shah         |
|         | Sunny Duhel  |
|         | Leong Zi Yin |
|         | Mohd Nasir   |
+---------+--------------+
5 rows in set (0.00 sec)

但是,这个表的行数是2589,我一个一个来做很繁琐,很费时间:

mysql> select count(*) from lz_chat_archive_dup1;
+----------+
| count(*) |
+----------+
|     2589 |
+----------+
1 row in set (0.00 sec)

我认为我可以使用类似这样的代码来仅更新/增加那一列,但我认为这不是 MySQL 的正确语法。您能否帮助更正代码以对其进行自定义以适应我的情况:

DECLARE @counter int
SET @counter = 383933
UPDATE #lz_chat_archive_dup1
SET @counter = counter = @counter + 1

因此,使用此代码,我想要实现的是增加 chat_id 列,以便下一个值始终比前一个值高 1 个整数。所以第一行是 383933,下一行应该是 383934、383935、383936……等等。

该表有 > 2000 行,所以这是它的摘录:

mysql> select time, endtime, chat_id from lz_chat_archive_dup1 LIMIT 20;
+------------+------------+---------+
| time       | endtime    | chat_id |
+------------+------------+---------+
| 1594948770 | 1594948928 | 383933  |
| 1594950285 | 1594950542 |         |
| 1594950708 | 1594951085 |         |
| 1594953554 | 1594955581 |         |
| 1594955956 | 1594956551 |         |
| 1595215646 | 1595218410 |         |
| 1595215648 | 1595216044 |         |
| 1595216110 | 1595216138 |         |
| 1595220816 | 1595221144 |         |
| 1595221046 | 1595221584 |         |
| 1595221448 | 1595221505 |         |
| 1595222302 | 1595222653 |         |
| 1595236468 | 1595236848 |         |
| 1595236954 | 1595237033 |         |
| 1595293418 | 1595293589 |         |
| 1595303280 | 1595304388 |         |
| 1595303410 | 1595303822 |         |
| 1595303675 | 1595303986 |         |
| 1595304153 | 1595306613 |         |
| 1595304878 | 1595304995 |         |
+------------+------------+---------+
20 rows in set (0.00 sec)

mysql>

【问题讨论】:

  • 记住关系数据库中的行代表无序集,定义'next'。
  • 按时间排序,而不是chat_id本身。
  • 这种情况下,我们需要查看时间列。

标签: mysql sql sql-update window-functions


【解决方案1】:

如果您可以使用从 1 开始的数字,按照 fullname 列的字母顺序,您可以尝试使用辅助表来运行更新:

CREATE TABLE updtab 
AS
SELECT
  ROW_NUMBER() OVER(ORDER BY fullname) AS chat_id
, fullname
FROM lz_chat_archive_dup1;

然后,运行更新:

UPDATE lz_chat_archive_dup1
  SET chat_id = (
    SELECT chat_id 
    FROM updtab 
    WHERE updtab.fullname=lz_chat_archive_dup1.fullname
    )
;

【讨论】:

    【解决方案2】:

    假设名称是唯一的,您可以使用join

    update lz_chat_archive_dup1 cad join
           (select cad2.*, row_number() over () as seqnum
            from lz_chat_archive_dup1 cad2
           ) cad2
           on cad2.name = cad.name
        set count = seqnum + 383933;
    

    我认为这可能是 MySQL 8+ 中推荐的方法。 (关于弃用变量的声明对于是否适用于UPDATE有点模糊。)

    您也可以使用变量。你的说法的问题是:

    SET @counter = counter = @counter + 1
    

    这甚至没有在表格中设置!它正在设置一个变量。使用:= 设置参数。我强烈推荐括号。所以,你可以这样做:

    DECLARE @counter int;
    SET @counter = 383933;
    
    UPDATE #lz_chat_archive_dup1
        SET counter = (@counter := @counter + 1);
    

    或者,在单个语句中:

    UPDATE #lz_chat_archive_dup1 cad CROSS JOIN
           (SELECT @counter := 383933) params
        SET cad.counter = (@counter := @counter + 1);
    

    【讨论】:

    • 这似乎任意将 id 附加到全名
    • @Strawberry 。 . .不知何故,我错过了你的观点,因为这似乎是 OP 所要求的。
    【解决方案3】:

    这是一种使用用户变量的方法:

    set @rn = 383933;
    update #lz_chat_archive_dup1
    set chat_id = (select @rn := @rn + 1)
    order by name;
    

    这将按照name 的字母顺序为每一行分配一个递增的数字。如果有联系,则未定义哪个名称将获得哪个数字(这是您应该在表中具有主键列的原因)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多