如何使用其中的Postgres type integer[]
数组将整个列/所有数据行重新转换为type integer
?
下面,user_email_id为type integer[]
\d emails
Column | Type
---------------+------------------------
id | integer
user_id | integer
user_email_id | integer[]
SELECT id, user_id, user_email_id FROM emails;
id | user_id | user_email_id
----+---------+---------------
65 | 1 | {98,110}
66 | 1 | {99}
对于user_email_id = {99}的行,这可行:
ALTER table emails
ALTER COLUMN user_email_id type integer
USING user_email_id[1]::INTEGER;
id = 66的预期输出;
\d emails
Column | Type
---------------+------------------------
id | integer
user_id | integer
user_email_id | integer
SELECT id, user_id, user_email_id FROM emails where id=66;
id | user_id | user_email_id
----+---------+---------------
66 | 1 | 99
但是,如果数组{98,110}
中有两个值,那会怎么做?在这种情况下,我想我要么必须转换为字符串,要么必须为id = 65的记录创建两行;?
答案 0 :(得分:1)
我不认为你想尝试将多元素数组混合成一个字符串或类似的东西,"列中的CSV"是一种众所周知的反模式,只会导致痛苦和痛苦。将多元素数组转换为多行最好。在评论中,您说没有FK引用此表,因此您不必担心创建新行。
你可以分步进行。首先使用unnest
和横向连接扩展数组以分隔列:
insert into emails (user_id, user_email_id)
select user_id, array[eid]
from emails,
unnest(user_email_id) as dt(eid)
where array_length(user_email_id, 1) > 1
那会给你这样的东西:
id | user_id | user_email_id
----+---------+---------------
65 | 1 | {98,110}
66 | 1 | {99}
X1 | 1 | {98}
X2 | 1 | {110}
X1
和X2
行来自65
。
然后摆脱刚刚扩展的行:
delete from emails
where array_length(user_email_id, 1) > 1
得到:
id | user_id | user_email_id
----+---------+---------------
66 | 1 | {99}
X1 | 1 | {98}
X2 | 1 | {110}
最后,一个带有USING子句的ALTER COLUMN来替换数组:
alter table emails
alter column user_email_id
type int using user_email_id[1]
那会让你:
id | user_id | user_email_id
----+---------+---------------
66 | 1 | 99
X1 | 1 | 98
X2 | 1 | 110