我有一个 PostgreSQL 服务器,其现有表具有两个固定宽度非唯一字符串(可变大小)列,例如:
| ID_STRING_A | ID_STRING_B |
| 'AAAA' | 'BBBB' |
| 'BBBB' | 'CCCC' |
| 'AAAA' | 'DDDD' |
现在我想计算两个列元素的整数表示并将它们存储到其他列中。结果应如下所示:
| ID_STRING_A | ID_STRING_B | ID_INT_A | ID_INT_B |
| 'AAAA' | 'BBBB' | 1 | 2 |
| 'BBBB' | 'CCCC' | 2 | 3 |
| 'AAAA' | 'DDDD' | 1 | 4 |
我基于答案的第一个方法是:
不幸的是,尽管 ID_STRING_A/B 上有索引,但我的更新部分似乎效率很低。虽然查询本身在几分钟内完成,但更新部分似乎并未结束。这是代码:
ALTER TABLE mytable ADD COLUMN ID_INT_B integer;
ALTER TABLE mytable ADD COLUMN ID_INT_A integer;
UPDATE mytable SET ID_INT_A = g.ID_INT_A , ID_INT_B = g.ID_INT_B FROM
(
WITH T( n , s ) AS
(
SELECT ROW_NUMBER() OVER ( ORDER BY s ) , s
FROM
(
SELECT ID_STRING_A FROM mytable
UNION
SELECT ID_STRING_B FROM mytable
) AS X( s )
)
SELECT m.ctid AS id_ , m.ID_STRING_A AS ID_STRING_A , m.ID_STRING_B AS ID_STRING_B , T1.n AS ID_INT_A , T2.n AS ID_INT_B FROM mytable AS m
JOIN T AS T1 ON m.ID_STRING_A = T1.s
JOIN T AS T2 ON m.ID_STRING_B = T2.s
) AS g
WHERE mytable.ctid = g.id_
我想你可以使用 ASCII 函数:
也许使用以下意图更清楚:
编辑,因为改变了这样的问题是可能的:
编辑,更新表
我有一种直觉,这可以以更简单的方式完成,但我将 cte 与自身交叉连接并使用 WHERE 过滤以同时更新两列:
需要注意的是,这是一次操作。如果以后决定加AABB,枚举就会出错
id_string_b
留给读者作为练习。