2

我将在 postgre 中将列的数据类型从“字符变化”更改为“bigint”。

旧列包含字符串“男性”和“女性”,现在我想将其更改为 0 或 1,每个代表男性或女性。

我认为一个简单的 Alter table ... Alter Column 不能解决这个问题,因为它不会进行男性 -> 0,女性 -> 1 的转换。

谁能让我知道最安全的方法是什么?

非常感谢。

4

4 回答 4

4

需要考虑的点

  1. 当您要使用 1 表示男性和 0 表示女性时,为什么要使用 bigint 数据类型?BIT/TINYINT 数据类型将起作用
  2. 在更改列的数据类型之前,您需要将 Male 更新为 1,将 Female 更新为 0
于 2013-01-17T10:43:11.223 回答
2

你们都在这方面走了很长一段路。这是一个简短的测试用例:

 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)
于 2013-01-18T07:52:34.250 回答
1

请注意,Postgres 能够ALTER COLUMN根据@ScottMarlowe 提供更简单的映射。

在大多数 RDBMS 中,这也可以按如下方式完成:

  1. 创建一个新的临时列,其中包含 Gender 的整数分类
  2. 更新表,使用 CASE / WHEN 将旧的 varchar 映射到新的 INT
  3. 删除旧的 varchar 列
  4. 将旧列添加回表中,这次使用新的数据类型
  5. 将临时 BIGINT 列中的数据复制回新列
  6. 删除临时 BIGINT 列

您可能还需要处理无效的映射 - 我已经使用案例 ELSE 完成了此操作。正如@Madhivanan 所建议的那样,使用 aBIGINT进行性别分类听起来太过分了。

SQL小提琴在这里

-- 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;
于 2013-01-17T10:50:03.890 回答
0

您必须首先更新表并将男性更改为 0,将女性更改为 1

然后你可以改变表...改变列

于 2013-01-17T10:46:13.767 回答