Страница 2 из 2
Добавлено: 21 мар 2006, 13:12
Vovchik
StS писал(а):Vovchik писал(а):
Процедуру ваяй хранимую. С циклом. И делай в ней что хошь.
Дык... эта... Я ж написал - SQL задачка. Думал что можно голым SQLем обойтись.
Эх, видно не судьба...
Нда? Задачка на перемешивание и чтоб одним предложением? Губа не дура.
хе хе
Добавлено: 21 мар 2006, 13:56
aissp
вообще то да - я трохи лохонулся - планировщик вычилсяет where clause а потом использует ее для update. Похоже только процедура спасет. Так что поторопился я с решением =)
Добавлено: 21 мар 2006, 18:41
hawk
Был бы в postgresql аналог rownum или analytic functions- задача решалась бы одним простым update.
А так действительно непросто.
Добавлено: 22 мар 2006, 07:54
StS
hawk писал(а):Был бы в postgresql аналог rownum или analytic functions- задача решалась бы одним простым update.
А так действительно непросто.
create table test2 (id int) with oids;
insert into test2 (id) (select id from test);
oid in test2 [trn]soderzhit nomer zapisi. A vse ravno ne rabotaet.
Vrode prostaya zadachka, a bez procedur nikak.[/trn]
Добавлено: 22 мар 2006, 21:22
hawk
StS писал(а):
create table test2 (id int) with oids;
insert into test2 (id) (select id from test);
oid in test2 [trn]soderzhit nomer zapisi. A vse ravno ne rabotaet.
Vrode prostaya zadachka, a bez procedur nikak.[/trn]
Тот, да не тот OID - всего лишь 4-х байтовый полуюникальный генератор.
В общем не зря его в 8.1 перестали включать по умолчанию. А rownum - это порядок в fetch-е. Т.е. select rownum,id from (select id from test order by id desc) - покажет все-равно 1,2,3 для rownum.
В целом в postgresql - задачка решается созданием двух sequences и потом их дропом. Конечно не слишком паралельно, но работать будет
Код: Выделить всё
begin;
create table test(id int,newid int);
insert into test (select generate_series,null from generate_series(1,1000));
-- to make a hole in a sequence, but keep it unique
delete from test where id=50;
delete from test where id=500;
commit;
-- query
begin;
set transaction ISOLATION LEVEL SERIALIZABLE;
-- to make row count stable;
create sequence t1;
create sequence t2;
create temporary table test_t1 (rownum int,id int) on commit drop;
create temporary table test_t2 (rownum int,id int) on commit drop;
insert into test_t1 (select nextval('t1'),id from (select id from test order by random()) a);
insert into test_t2 (select nextval('t2'),id from (select id from test order by random()) a);
update test set newid = (select t1.id from test_t1 t1,test_t2 t2 where t2.id=test.id and t2.rownum=t1.rownum);
drop sequence t1;
drop sequence t2;
commit;
В Oracle было бы чуть более компактно и без создания sequences
Код: Выделить всё
with
t1 as (select rownum myrownum, id from (select id from test order by random())),
t2 as (select rownum myrownum, id from (select id from test order by random()))
select t1.id,t2.id from t1,t2 where t1.myrownum=t2.myrownum;
это собственно запрос, а дальше по желанию update , merge и прочее.
второй random - конечно не обязателен, просто смотрится симметричнее

Добавлено: 23 мар 2006, 09:13
StS
[trn]Uh ty! Rabotaet!
Spasibo[/trn]
Добавлено: 23 мар 2006, 09:53
Vovchik
StS писал(а):[trn]Uh ty! Rabotaet!
Spasibo[/trn]
Вообще то это все только ежели изначальные id - последовательные числа без дырок. Но это уж кому чего надо.
Добавлено: 23 мар 2006, 11:05
StS
Vovchik писал(а):
Вообще то это все только ежели изначальные id - последовательные числа без дырок. Но это уж кому чего надо.
[trn]Net. U menya chilsla neposledovatel'nye.[/trn] rowid [trn]dolzhny byt' posledovatel'nymi i bez dyrok. Powtomu cherez oid i ne rabotaet.[/trn]