MySQL:如何将新的 id 列添加到 table,按旧列分组?
MySQL: How do you add new id column to the table, group by the old column?
我正在尝试将列 new_id
添加到 MySQL Workbench 中的 table,但我希望此 new_id
是 GROUP BY 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 |
+----------+--------+
我在这里错过了什么....?
谢谢!!!
你想要的(遗憾的是)不能用自动增量列来完成。
替代解决方案可以是:
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 并为您提供了 return 中的唯一性 new_id。您现在可以通过 INNER JOIN 加入此 new_id 对抗候选人 table 并获得您想要的结果。
添加列,然后使用 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;
您对 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
查询可能是您最好的长期选择。这样,您可以在需要时根据最新数据计算密集排名,而无需担心在实际 table.
中维护它
输出:
此处演示:
我正在尝试将列 new_id
添加到 MySQL Workbench 中的 table,但我希望此 new_id
是 GROUP BY 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 |
+----------+--------+
我在这里错过了什么....? 谢谢!!!
你想要的(遗憾的是)不能用自动增量列来完成。
替代解决方案可以是:
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 并为您提供了 return 中的唯一性 new_id。您现在可以通过 INNER JOIN 加入此 new_id 对抗候选人 table 并获得您想要的结果。
添加列,然后使用 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;
您对 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
查询可能是您最好的长期选择。这样,您可以在需要时根据最新数据计算密集排名,而无需担心在实际 table.
输出:
此处演示: