2015-03-20 4 views
8

Дайте массив так:Как вставить элементы массива в PostgreSQL таблицу

my_array = [2,3,5,23,4] 

и таблицу, как это:

column1 | column2 
---------+---------- 
    1  |  
    2  |  
    3  |  
    4  |  
    5  | 

Как я могу вставить массив значений в таблицу. Грубо говоря, я хочу сделать что-то подобное с SQL:

for item in my_array: 
UPDATE my_table SET colum2 = item 

Обновленная таблица должна быть, как это

column1 | column2 
---------+---------- 
    1  |  2 
    2  |  3 
    3  |  5 
    4  |  23 
    5  |  4 

UPDATE: Я использую Python psycopg2, но мне интересно, если есть способ, с чистый SQL.

+0

Вы хотите добавить весь массив в один столбец или в отдельный столбец или в отдельную строку –

+1

Какой язык программирования вы используете? Как вы определили этот массив на своем языке? Что делать, если массив имеет более или менее элементы, чем у вас есть строки в таблице? Является ли позиция индекса элемента всегда равной значению в 'column1'?(Помните: строки в реляционной таблице *** не сортируются ***, поэтому вы не можете сопоставлять элементы массива в строки таблицы по «позиции») –

+0

Я использую Python с psycopg2, но мне интересно, могу ли я сделать это с чистым SQL. Массив всегда будет иметь такое же количество элементов, как строки в таблице. Я буду использовать параметр stat, чтобы обеспечить правильное значение массива в правой строке. – ustroetz

ответ

3

Вы должны каким-то образом генерировать массив «индекс» для каждой строки в таблице.

Если величина column1всегда соответствует индексу массива, вы можете сделать это, как это.

update test 
    set column2 = (array[2,3,5,23,4])[column1]; 

Однако, если значение в column1 не отражает индекс массива, вам необходимо сгенерировать индекс массива на основе порядка сортировки в таблице. Если это так, вы можете сделать что-то вроде этого:

with numbered_data as (
    select ctid, 
     row_number() over (order by column1) as rn --<< this generates the array index values 
    from test   
) 
update test 
    set column2 = (array[2,3,5,23,4])[nd.rn] 
from numbered_data nd 
where nd.ctid = test.ctid; 

Если таблица имеет правильный первичный ключ, то вы можете использовать то, что вместо ctid колонки.

+0

Не могли бы вы объяснить символ символом правой стороны 'set column2 = (array [foo]) [bar]' thing? – LauriK

-5

как этот

insert into my_table(..., my_column, ...) 
select ..., item, ... 
from dual, ... 
where item in (<your array>) 
+1

'double' не имеет особого значения в Postgres. И это даже не близко к ответу. –

6

В Postgres 9.4 используйте для этого WITH ORDINALITY. Быстрее и чище, чем что-либо еще.

UPDATE test t 
SET column2 = a.column2 
FROM unnest('{2,3,5,23,4}'::int[]) WITH ORDINALITY a(column2, column1) 
WHERE t.column1 = a.column1; 

Предполагая, что column1 представляет положение column2 в данном массиве, это только обновляет столбцы, которые должны быть обновлены и не трогают других строк (например, простой запрос в ответе @ a_horse).

Порядковый положение элемента также индекс массива по умолчанию в 1-мерном массиве, но Postgres позволяет произвольные индексы массива:

Это работает Вне зависимости от фактических индексов массива ,

Смежные вопросы