【问题标题】:MySQL: How do you add new id column to the table, group by the old column?MySQL:如何将新的 id 列添加到表中,按旧列分组?
【发布时间】:2017-11-26 11:32:55
【问题描述】:

我正在尝试将列 new_id 添加到 MySQL Workbench 中的表中,但我希望将此 new_id 分组为 old_id

我尝试了下面的代码。 new_id 是自动增加的,但不是按old_id 分组的。

ALTER TABLE candidate
ADD COLUMN new_id int not null auto_increment UNIQUE FIRST,
ADD PRIMARY KEY(old_id, new_id);

以下是我得到的:

+----------+--------+
| old_id   | new_id |
+----------+--------+
| 00132004 |    1   |
| 00132004 |    2   |
| 00132004 |    3   |
| 00132004 |    4   |
| 00118685 |    5   |
| 00118685 |    6   |
| J99999   |    7   |
| J99999   |    8   |
| J99988   |    9   |
| J99987   |   10   |
+----------+--------+

但这是我想要得到的:

+----------+--------+
| old_id   | new_id |
+----------+--------+
| 00132004 |    1   |
| 00132004 |    1   |
| 00132004 |    1   |
| 00132004 |    1   |
| 00118685 |    2   |
| 00118685 |    2   |
| J99999   |    3   |
| J99999   |    3   |
| J99988   |    4   |
| J99987   |    5   |
+----------+--------+

我在这里错过了什么......? 谢谢!!!

【问题讨论】:

  • 自动增量列将为每条新记录生成一个新值。它不会(也不应该)生成与不同行中的值重复的值。如果您真的需要这样的东西,您将必须创建一个插入前触发器并计算要放入列中的值。
  • 每行自动递增。你无法改变这一点。如果您想要一个自动递增的非唯一 id,您可能必须为它编写一个自定义函数。

标签: mysql group-by auto-increment alter-table


【解决方案1】:

您对new_id 的新要求将无法使该列自动递增,因为这样这些值将不是唯一的或递增的。

您正在寻找的是一种称为密集秩的东西。 MySQL 没有对此的内置支持,但您可以使用会话变量来模拟它:

SET @dense_rank = 0;
SET @old_id = NULL;

SELECT
    @dense_rank:=CASE WHEN @old_id = old_id
                      THEN @dense_rank ELSE @dense_rank + 1 END AS dr,
    @old_id:=old_id AS old_id,
    new_id
FROM candidate
ORDER BY new_id

请注意,由于 MySQL 不支持任何自动维护密集排名的干净方式,因此SELECT 查询可能是您最好的长期选择。这样,您可以在需要时从最新数据中计算密集排名,而无需担心在实际表中维护它。

输出:

演示在这里:

Rextester

【讨论】:

    【解决方案2】:

    你想要的(很遗憾)不能用自动增量列来完成。

    另一种解决方案可能是:

    CREATE TABLE mytab (new_id int not null auto_increment,
    old_id VARCHAR(200),
    FOREIGN KEY old_id (old_id) REFERENCES candidate(old_id));
    
    CREATE UNIQUE INDEX old_id_idx ON mytab(old_id);
    

    这保证了唯一的 old_ids 并给你一个唯一的 new_id 作为回报。您现在可以使用 INNER JOIN 将这个 new_id 与候选表连接起来,并获得您想要的结果。

    【讨论】:

      【解决方案3】:

      添加列,然后使用update进行设置:

      set @old_id = '', @rn = 0;
      
      update candidate
          set new_id = if(@old_id = old_id, @rn,
                          if(@old_id := old_id, @rn := @rn + 1, @rn := @rn + 1)
                         )
          order by old_id;
      

      【讨论】:

      • Gordon,如果要将 数据添加到表中,这可能会变得很麻烦,因为我们必须每次都运行此更新(可能)。
      猜你喜欢
      • 1970-01-01
      • 2022-10-06
      • 2013-10-29
      • 1970-01-01
      • 2021-05-23
      • 1970-01-01
      • 2017-02-20
      • 2020-09-08
      • 2020-07-14
      相关资源
      最近更新 更多