[Oracle] Implementacja logiki z excel

0

Mam pewien problem, piszę logikę zawartą w excelu w Oracle SQL.
Tabelka wynikowa ma poniższe dane:

UMOWA || PRZEKR
100 || 0
100 || 150
100 || 450

I teraz chcę nową kolumn WYNIK która powinna mieć logikę:

DLA TRZECIEGO REKORDU:

JEŻELI ( PRZEKR <= UMOWA;0;PRZEKR - UMOWA ) - SUMA (WYNIK$1:WYNIK$2)

Czyli powinien być wynik:

UMOWA || PRZEKR || WYNIK
100 || 0 || 0
100 || 150 || 50 ---> (150-100) - 0
100 || 450 || 300 --- > (450-100) - 50

Mam prosty CASE w sql:

CASE WHEN p3.PRZEKR < UMOWA THEN 0 ELSE p3.PRZEKR - UMOWA END 

Nie wiem jak w zapytaniu dodać tą dynamiczną SUMĘ, ma ktoś jakąś propozycję?

0

W excelu masz identyfikator wiersza i w formule możesz odnosić się do poprzednich wierszy, a w SQLu jak będziesz miał tabelkę, co to znaczy "poprzednie" ?

0
yarel napisał(a):

W excelu masz identyfikator wiersza i w formule możesz odnosić się do poprzednich wierszy, a w SQLu jak będziesz miał tabelkę, co to znaczy "poprzednie" ?

No tak nie dopisałem co jest jeszcze w tabelce. Wygląda to tak:

DATA || UMOWA || PRZEKR || WYNIK
18/11/16 || 100 || 0 || 0
18/11/19 || 100 || 150 || 50 ---> (150-100) - 0
19/11/22 || 100 || 450 || 300 --- > (450-100) - 50

Czyli PRZEKR można powiedzieć jest wyliczana narastająco po dniach od początku roku (czyli partition by YEAR).
Dla danego produktu są dane tylko dla niektórych DNI - nie ma wszystkich dni w tabeli, tylko tam gdzie są dane.

Moja kolumna WYNIKI ma być wyliczana również narastająca i powinna odejmować SUME z poprzednich dni od początku roku.

1

SUM() OVER()

0

Skoro masz datę, to można sumować po zdefiniowanym okienku.

  1. Wyliczasz WYNIK
select t.*, case ... end wynik from tabelka; 
  1. Wyliczasz z tak przygotowanego zbioru sumy narastajace:
select 
    u.*,
    wynik - sum(wynik) over (partition by year order by year RANGE BETWEEN UNBOUNDED AND CURRENT ROW)  suma_narastajaca
from 
  (select t.*, case ... end wynik from tabelka) u;

Nie testowałem, ale jak zrobisz przykładowe dane na sqlfiddle, to będzie na czym sprawdzać ;)

0
Marcin.Miga napisał(a):

SUM() OVER()

Możesz rozwinąć myśl?

, p4.wynik - (SUM(p4.wynik ) OVER (partition by p4.PRODUT, p4.YEAR order by p4.DZIEN RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW))  B1

Mam taką na razie formułe, jednak ta suma bierze mi pod uwagę również CURRENT ROW w range between. Czy się użyć żeby ten range ustawić od pierwszego rekordu do coś w s tylu PREVIOUS ROW - w sensie z poprzedniego dostępnego dnia (jeżeli nie ma poprzedniego to 0?

1

Masz funkcję LAG, która "zagląda do poprzednich wierszy" i może skorygować sumę.

1
yarel napisał(a):

Masz funkcję LAG, która "zagląda do poprzednich wierszy" i może skorygować sumę.

Oo widzisz! Nie znałem takiej funkcji, ale już rzuciłem okiem na dokumentację i faktycznie o coś takiego chodziło.
Wyliczenia poprzedniej wartości zrobiłem mniej więcej tak:

NVL(LAG(w1.WYNIK,1) OVER (partition by w1.PRODUKT, w1.YEAR ORDER BY w1.DZIEN),0) as PREV_VALUE

I później w kolejnym kroku odjąłem tylko WYNIK - PREV_VALUE i wygląda że jest w porządku.

DzięKI!

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