Лучше всего сделать это за одну транзакцию:
UPDATE token
SET word = (
SELECT string_agg(word, ' ' ORDER BY position)
FROM token
WHERE id = ANY('{5,8,6,7}'::int[])
)
,id = nextval('token_id_seq')
WHERE id = ('{5,8,6,7}'::int[])[1];
DELETE FROM token
WHERE id = ANY('{5,8,6,7}'::int[])
AND id <> ('{5,8,6,7}'::int[])[1];
Замените '{5,8,6,7}'::int[]
параметром массива целых чисел.
Я получаю новый id
из последовательности, которая, я полагаю, существует.
Далее я предполагаю, что упорядочение в массиве совпадает с упорядочением по позиции. Альтернативная версия приведена ниже.
id
для обновления является первым элементом массива.
Упорядочение слов может быть выполнено внутри агрегатной функции (начиная с PostgreSQL 9.0). Прочитайте об этом в руководстве .
Ответ на дополнительный вопрос
Упорядочить выбранные строки в соответствии с последовательностью элементов массива:
SELECT rn, t.*
FROM (
SELECT id
,row_number() OVER () AS rn
FROM (SELECT unnest('{5,8,6,7}'::int[]) id) x
) x
JOIN token t USING (id)
ORDER BY rn;
Или ... делает то же самое с разными техниками, работает и в старых версиях Postgres:
SELECT rn, t.*
FROM (
SELECT rn
,a[rn] AS id
FROM (SELECT '{5,8,6,7}'::int[] AS a
,generate_series(1, array_upper('{5,8,6,7}'::int[], 1)) rn) x
) x
JOIN token t USING (id)
ORDER BY rn;
Комбинация
Используйте это в выражении UPDATE:
UPDATE token
SET word = (
SELECT string_agg(word, ' ' ORDER BY rn)
FROM (
SELECT rn
,a[rn] AS id
FROM (
SELECT '{5,8,6,7}'::int[] AS a
,generate_series(1, array_upper('{5,8,6,7}'::int[], 1)) rn) x
) x
JOIN token t USING (id)
)
,id = nextval('token_id_seq')
WHERE id = ('{5,8,6,7}'::int[])[1];