Otra tabla, con múltiples índices únicos:
create table utest(id integer, position integer not null, unique(id, position));
test=# \d utest
Table "public.utest"
Column | Type | Modifiers
----------+---------+-----------
id | integer |
position | integer | not null
Indexes:
"utest_id_key" UNIQUE, btree (id, "position")
Algunos datos:
insert into utest(id, position) select generate_series(1,3), 1;
insert into utest(id, position) select generate_series(1,3), 2;
insert into utest(id, position) select generate_series(1,3), 3;
test=# select * from utest order by id, position;
id | position
----+----------
1 | 1
1 | 2
1 | 3
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2
3 | 3
(9 rows)
Creé un procedimiento que actualiza los valores de posición en el orden correcto:
create or replace function update_positions(i integer, p integer)
returns void as $$
declare
temprec record;
begin
for temprec in
select *
from utest u
where id = i and position >= p
order by position desc
loop
raise notice 'Id = [%], Moving % to %',
i,
temprec.position,
temprec.position+1;
update utest
set position = position+1
where position=temprec.position and id = i;
end loop;
end;
$$ language plpgsql;
Algunas pruebas:
test=# select * from update_positions(1, 2);
NOTICE: Id = [1], Moving 3 to 4
NOTICE: Id = [1], Moving 2 to 3
update_positions
------------------
(1 row)
test=# select * from utest order by id, position;
id | position
----+----------
1 | 1
1 | 3
1 | 4
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2
3 | 3
(9 rows)
Espero que ayude.