我将在 postgre 中将列的数据类型从“字符变化”更改为“bigint”。
旧列包含字符串“男性”和“女性”,现在我想将其更改为 0 或 1,每个代表男性或女性。
我认为一个简单的 Alter table ... Alter Column 不能解决这个问题,因为它不会进行男性 -> 0,女性 -> 1 的转换。
谁能让我知道最安全的方法是什么?
非常感谢。
我将在 postgre 中将列的数据类型从“字符变化”更改为“bigint”。
旧列包含字符串“男性”和“女性”,现在我想将其更改为 0 或 1,每个代表男性或女性。
我认为一个简单的 Alter table ... Alter Column 不能解决这个问题,因为它不会进行男性 -> 0,女性 -> 1 的转换。
谁能让我知道最安全的方法是什么?
非常感谢。
需要考虑的点
你们都在这方面走了很长一段路。这是一个简短的测试用例:
create table test (username text, sex text);
insert into test values ('bob','male'),('sandra','female'),('stan','male'),('sue','male');
select * from test;
username | sex
----------+--------
bob | male
sandra | female
stan | male
sue | male
(4 rows)
alter table test alter column sex type int using case when sex='male' then 0 when sex='female' then 1 end;
select * from test;
username | sex
----------+-----
bob | 0
sandra | 1
stan | 0
sue | 0 (4 rows)
请注意,Postgres 能够ALTER COLUMN
根据@ScottMarlowe 提供更简单的映射。
在大多数 RDBMS 中,这也可以按如下方式完成:
您可能还需要处理无效的映射 - 我已经使用案例 ELSE 完成了此操作。正如@Madhivanan 所建议的那样,使用 aBIGINT
进行性别分类听起来太过分了。
-- Add new Column
ALTER TABLE SomeTable ADD GenderTypeId BIGINT;
-- Map old to new
UPDATE SomeTable SET GenderTypeId =
CASE
WHEN GenderVarchar = 'male'
THEN 0
WHEN GenderVarchar = 'female'
THEN 1
ELSE
-1 -- Invalid source data
END;
-- Drop old
ALTER TABLE SomeTable DROP COLUMN GenderVarchar;
更新
如果您需要使用与原始列相同的名称,那么您还需要重新添加旧列,这次使用新的数据类型,然后再次复制数据。(我给它起了一个新名字)
ALTER TABLE SomeTable ADD Gender BIGINT;
-- Copy the data across
UPDATE SomeTable SET Gender = GenderTypeId;
-- Drop the temporary column
ALTER TABLE SomeTable DROP COLUMN GenderTypeId;
您必须首先更新表并将男性更改为 0,将女性更改为 1
然后你可以改变表...改变列