Edycja wartości rekordów na zasadzie kolejki fifo

0

Cześć,
Mam daną tabelę:
ID ... Count
i rekordy:
1 ... 100
2 ... 3
3 ... 200

Chcę za pomocą 1 zapytania odjąć 204 "Count", tak by najpierw zużył tyle ile może z najstarszego rekordu, a więc wynikiem powinny być rekordy:

1 ... 99
2 ... 0
3 ... 0

Jakiś pomysł?

0

Ja tam nie wiem ale wynik oczekiwany to mi bardziej do LIFO pasuje niż do FIFO, ale zacznijmy od tego jaka baza i w której wersji?

0

MariaDB 9.4.0

0

Coś w ten deseń:

select
    id
    ,counter
    ,wynik
from (        
    SELECT 
       t.* 
       ,case 
          when @s > 0 then
             case 
                when @s-t.count > 0 then 
                    0 
                else 
                    t.count-@s 
                end
       else 
          t.count 
       end wynik 
       ,@s:[email protected]
       ,@rs:=@rs+t.count 
    FROM 
       t
       JOIN (SELECT 
             @rs :=0
             ,@s :=204
             )r
    order by 
       id desc) w

http://www.sqlfiddle.com/#!9/d025dd/3

0

A bez czarów to tak:

select t1.id, t1.count,
case when sum(t2.count) >= 204
then
  -- jeżeli suma elementów o większych id wystarczyła, zwróc normalny count
  t1.count
else
  case when t1.count + sum(t2.count) >= 204 then
    -- jeżeli w tym wierszu spełnimy warunek, wylicz resztę
    t1.count + sum(t2.count) - 204
  else
    -- wiersze, dla których suma narastająca jest zbyt mała
    0
  end
end
from t as t1 left join t as t2 on t2.id > t1.id
group by t1.id
1

A cóż to za konstrukcja? Gdzie można przerobić tę lekcję?

@jarekczek (w komentarzu się nie zmieszczę) to taki myk który pozwala wykorzystać zmienne do liczenia sumy bieżącej (i nie tylko)

Zapytanie:

select 
   id
  ,@rs --zmienna przed przypisaniem
  ,@rs:=@rs+t.id rs --zwiększenie sumy o aktualną warość id
  ,@rs --zmienna po przypisaniu
FROM 
    t
  JOIN (SELECT 
--inicjalizacja zmiennej @rs
		 @rs :=0
		 ) r
order by 
   id asc

taka konstrukcja robi sumę bieżącą: @rs:=@rs+t.id ale zwróć uwagę, że jeżeli @rs=0 i w pierwszym rekordzie id = 1 to zapytanie zwróci:

1,0,1,1

Czyli przetwarza od lewej do prawej najpierw wartość @rs, później dodanie wartosci z id, później wartość @rs po dodaniu id, w sumie analogicznie jakbyś zrobił pętle, w pseudokodzie:

@rs=0
@dane = select id from t order by id
petla po @dane od początku do konca {
   print @dane.id
   print @rs
    @rs=@[email protected]
   print @rs
   print @rs
}

Czyli iteracja bez pętli i magii ;)

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