Измените столбец из Integer [] (ARRAY) в Integer в Postgres - PullRequest
0 голосов
/ 24 мая 2018

Как мне преобразовать весь столбец / все строки данных с массивами 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;?

1 Ответ

0 голосов
/ 24 мая 2018

Я не думаю, что вы хотите попытаться объединить многоэлементные массивы в строку или что-то в этом роде, «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}

И, наконец,ALTER COLUMN с предложением USING для замены массивов:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...