【发布时间】:2013-01-17 10:39:48
【问题描述】:
我将在 postgre 中将列的数据类型从“字符变化”更改为“bigint”。
旧列包含字符串“男性”和“女性”,现在我想将其更改为 0 或 1,分别代表男性或女性。
我认为一个简单的Alter表...Alter Column并不能解决这个问题,因为它不会进行男性-> 0,女性-> 1的转换。
谁能告诉我最安全的方法是什么?
非常感谢。
【问题讨论】:
标签: sql postgresql
我将在 postgre 中将列的数据类型从“字符变化”更改为“bigint”。
旧列包含字符串“男性”和“女性”,现在我想将其更改为 0 或 1,分别代表男性或女性。
我认为一个简单的Alter表...Alter Column并不能解决这个问题,因为它不会进行男性-> 0,女性-> 1的转换。
谁能告诉我最安全的方法是什么?
非常感谢。
【问题讨论】:
标签: sql postgresql
需要考虑的点
【讨论】:
你们都在解决这个问题。这是一个简短的测试用例:
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 建议的那样,使用BIGINT 进行性别分类听起来太过分了。
-- 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
然后你就可以Alter table ... Alter Column
【讨论】: