如何设置以组ID为前缀的每行唯一ID值
原始数据表
| ID | Value | Gr_Id | Gr_Value |
|---|---|---|---|
| NULL | A | 1 | A |
| NULL | B | 1 | A |
| NULL | C | 2 | B |
| NULL | D | 2 | B |
| NULL | E | 2 | B |
| NULL | F | 3 | C |
预期结果表
| ID | Value | Gr_Id | Gr_Value |
|---|---|---|---|
| 101 | A | 1 | A |
| 102 | B | 1 | A |
| 201 | C | 2 | B |
| 202 | D | 2 | B |
| 203 | E | 2 | B |
| 301 | F | 3 | C |
实现方案
核心逻辑:按Gr_Id分组后给组内每行生成从1开始的序号,通过Gr_Id * 100 + 组内序号计算得到目标ID,即可满足ID前缀为组ID、全局唯一的要求。如果组内行数可能超过99,将乘100改为乘1000即可适配更大的组容量。
MySQL 8.0+/MariaDB 10.2+/PostgreSQL/Oracle/SQL Server(支持窗口函数的数据库)
直接用标准窗口函数实现:
SELECT Gr_Id * 100 + ROW_NUMBER() OVER(PARTITION BY Gr_Id ORDER BY Value) AS ID, Value, Gr_Id, Gr_Value FROM 你的表名;
低版本MySQL(不支持窗口函数)
用变量实现分组排序:
SELECT (t.Gr_Id * 100 + t.row_num) AS ID, t.Value, t.Gr_Id, t.Gr_Value FROM ( SELECT *, @row_num := IF(@current_gr = Gr_Id, @row_num + 1, 1) AS row_num, @current_gr := Gr_Id FROM 你的表名 ORDER BY Gr_Id, Value ) t, (SELECT @current_gr := NULL, @row_num := 0) init;
若需要更新原表的ID字段(以MySQL为例)
UPDATE 你的表名 a JOIN ( SELECT (Gr_Id * 100 + ROW_NUMBER() OVER(PARTITION BY Gr_Id ORDER BY Value)) AS new_id, Value, Gr_Id, Gr_Value FROM 你的表名 ) b ON a.Value = b.Value AND a.Gr_Id = b.Gr_Id AND a.Gr_Value = b.Gr_Value SET a.ID = b.new_id;
内容的提问来源于stack exchange,提问作者Petr Alexa
相关产品推荐
相关产品推荐

