Чтобы обновить несколько недублированных строк одновременно, используя «Группировать по» - PullRequest
0 голосов
/ 30 ноября 2011

Я последовал за помощью из Генерация случайного числа не дублированного случайного числа в [0, 1001] через цикл .

Но я не могу применить это к своему делу. Когда я делаю:

update weighed_directed_edge set endpoint= trunc(1000 * random()+ 1)
from  generate_series(1,10) group by 1 where startpoint= from_point;

для обновления конечной точки. Если она жалуется:

ERROR:  syntax error at or near "group"
LINE 1: ...nc(1000 * random()+ 1) from generate_series(1,10) group by 1.

Я тоже пробовал:

insert into weighed_directed_edge (startpoint,endpoint)
values (from_point, trunc((1000 * random()+ 1) )
FROM generate_series(1, directed2number)
GROUP  BY 1 ;

insert into weighed_directed_edge (startpoint, endpoint, costs)
select 1, trunc(1000 * random()+ 1) from  generate_series(1,10) group by 1,1;

Не работает. Мне нужно выбрать начальную и конечную точки из тех же точек, что и из другой таблицы, чтобы заполнить таблицу weighed_directed_edge.

  • таблица точек пересечения: имеется 1001 пересечение.

                                 Table "public.cross_point"
        Column    |  Type   |                                   Modifiers                              
    --------------+---------+---------------------------------------------------------------------
     intersection | integer | not null default nextval  ('intersection_intersection_seq'::regclass)
     x_axis       | integer | not null
     y_axis       | integer | not null
    Indexes:
        "intersection_pkey" PRIMARY KEY, btree (intersection)
        "intersection_x_axis_key" UNIQUE, btree (x_axis, y_axis)
    
  • таблица weighed_directed_edge:

           Table "public.weighed_directed_edge"
           Column   |       Type       | Modifiers 
        ------------+------------------+-----------
         startpoint | integer          | 
         endpoint   | integer          | 
         costs      | double precision | 
        Indexes:
            "weighed_directed_edge_startpoint_key" UNIQUE, btree (startpoint, endpoint)
        Foreign-key constraints:
            "weighed_directed_edge_endpoint_fkey" FOREIGN KEY (endpoint) REFERENCES cross_point(intersection)
            "weighed_directed_edge_startpoint_fkey" FOREIGN KEY (startpoint) REFERENCES cross_point(intersection)
    
  • Случайное число конечной точки (получить из столбца 1001 точек случайным образом) соответствует каждой начальной точке (получить из столбца точек последовательно). Номер конечной точки в [1,7].

  • Расходы будут основаны на расстоянии между начальной точкой и конечная точка.

Требования:

  • Комбинация начальной и конечной точек должна быть уникальной.

  • Набор начальных точек содержит все 1001 пересечение от таблицы cross_point

  • Конечные точки поступают из одного и того же набора точек пересечения.

  • В каждой точке звезды не более 7 совпадений в конечной точке (максимальное пересечение дороги с 7 дорогами), и номер соответствия конечной точки выбирается случайным образом.

Я пропустил расчет затрат в следующем коде:

--The largest number of intersection chosen is 7, but this could be altered
create or replace function popluate_weighed_directed_edge() returns void as $$
declare
from_point integer;
to_point integer;
directed2number integer; --the number of node this startpoint leads to
counter integer;
factor float; 
weight numeric;
start_pointer record;

begin
for start_pointer in select * from cross_point
loop
from_point := start_pointer.intersection;
    directed2number := trunc(Random()*7+1);
    counter := directed2number;
        while counter > 0
        loop
insert into weighed_directed_edge (startpoint) select from_point from  generate_series(1,10) ;
update weighed_directed_edge set endpoint= trunc(1000 * random()+ 1) from  generate_series(1,10) group by 1 where startpoint= from_point ;
update weighed_directed_edge set costs= trunc(1000 * random()+ 1) from  generate_series(1,10) group by 1 where startpoint= from_point ;
        counter := counter - 1;
        end loop;
end loop;
end
$$ language plpgsql;

1 Ответ

1 голос
/ 01 декабря 2011

Внутри цикла вы можете нарисовать случайное число и вставить его (и уменьшить значение счетчика цикла), если оно не существует. Псевдокод :

while (counter > 6) 
loop:
  this = 1+ random() *1000
  insert into weighed_directed_edge (startpoint, endpoint, costs)
  VALUES ( :frompoint, :this, xxx* random() )
  WHERE NOT EXISTS (
    SELECT(*) FROM weighed_directed_edge nx
    WHERE nx.startpoint = :frompoint
    AND nx.endpoint = :this
    );

  if (rowcount > 0) counter -= 1;
end loop;
...