Oracle - pętla alokująca wartości po nadanych priorytetach

0

Proszę o pomoc,

Przykładowo mam taką tabele w bazie danych:

VALUE1 VALUE2 ID PRIORITY
150 190 1 3
150 90 1 6
150 10 1 2

Chciałbym otrzymać coś takiego:

VALUE1 VALUE2 ID PRIORITY
140 190 1 3
0 90 1 6
10 10 1 2

Potrzebuję napisać kod, który pozwoli zaalokować wartości w kolumnie VALUE1 zgodnie z priorytetem z kolumny PRIORITY na podstawie wartości z kolumny VALUE2. Dla jednej wartości w kolumnie ID może występować wiele priorytetów, lecz wartość VALUE1 przy każdym z nich zawsze będzie taka sama tj.

  1. Najwyższy priorytet to 2, więc zaczynamy sprawdzanie od tego wiersza. VALUE2 = 10, więc VALUE1 = 10,
  2. Kolejny priorytet to 3, VALUE2 = 190, przypisujemy do VALUE1 wartość 140, (10 + 140 = 150, czyli wartość kolumny VALUE1)
  3. Priorytet z numerem 6 posiada wartość kolumny VALUE2 = 90, program powinien nadać wartość 0 w kolumnie VALUE1, ponieważ już przy PRIORITY = 3 osiągnął wartość 150.

Może zdarzyć się taka sytuacja, że jakiś ID będzie posiadać takie same priorytety o różnych VALUE2, wtedy program powinien przypisać proporcjonalnie wartości do VALUE1. Różnych numerów ID w tabeli może być ponad 2000.

Jak coś opisałem niejasno to oczywiście postaram się to doprecyzować. Pewnie potrzebowałbym jakąś pętle, która wykona opisane powyżej czynności, jednak nie wiem jak ją napisać. Bardzo proszę o pomoc.

Przykładowa tabela:

create table t (value1 number, value2 number, id number, priority number);

insert into t values (150, 190, 1,3);
insert into t values (150, 90, 1,6);
insert into t values (150, 10, 1,2);
1

Może zdarzyć się taka sytuacja, że jakiś ID będzie posiadać takie same priorytety o różnych VALUE2, wtedy program powinien przypisać proporcjonalnie wartości do VALUE1

Nie wiem co masz na myśli pisząc proporcjonalnie...Najlepiej jak byś dał przykład id z takim samym priorytetem i jakiego wyniku oczekujesz

Chciałeś zrobić update na tabelce czy wstawić dane do nowej tabelki? Ja zrobiłem update. Możesz przerobić na procedurę/funkcję

declare
   value1_         number;
   current_value1_ number; 
begin
   for i_ in (select id, value1 from t group by id, value1)  loop
      value1_ := i_.value1;
      for rec_ in (select t.*, t.rowid  from t t where t.id = i_.id order by t.priority) loop
         current_value1_ :=  least(value1_, rec_.value2);
         --dbms_output.put_line('priority = '||rec_.priority||'  value1 = '||current_value1_);
         update t set value1 = current_value1_ where rowid = rec_.rowid;
         value1_ := value1_ - current_value1_;     
      end loop;   
   end loop; 
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1