Suma nieujemnych kwot sald w podziale na status klienta wraz z filtrowaniem dat

0

Witam,

Przygotowuję kreator raportu rozliczeń klientów porównujący dane historyczne (użytkownik wybiera trzy daty zrzutów z bieżącego i dwóch ostatnich miesięcy w programie) i potrzebowałbym pomocy w napisaniu zapytania (PostgreSQL), które zwróci mi w wierszach agregację dat sald (po miesiącach w pierwszej kolumnie), a w kolejnych kolumnach odpowiednio sumę sald wszystkich klientów aktywnych, którzy mają sumaryczną kwotę swoich faktur >0 (uwzględnienie tylko klientów z zaległościami), nieaktywnych z zaległością oraz total. Chodzi mniej więcej o coś takiego:

screenshot-20210709070823.png

Próbowałem już zapytania jak poniżej:

select
to_char(data_salda, 'YYYY-MM') as data,

(Case when sum(kwota)>'0,00' and status='Aktywny' then sum(kwota) else '0,00' end) Aktywni,
(Case when sum(kwota)>'0,00' and status='Nieaktywny' then sum(kwota) else '0,00' end) Nieaktywni,      
(Case when sum(kwota)>'0,00' then sum(kwota) else '0,00' end) Razem   

from klienci_rozliczenia_historia where (data_salda='.......' or data_salda='......' or data_salda='.....')

group by data_salda,status,to_char(data_salda, 'YYYY-MM') order by to_char(data_salda, 'YYYY-MM')

Jednak (na przykładzie innych faktycznych testowych danych w mojej bazie) agregacja nie działa poprawnie - wrzuca każdy status do osobnego wiersza (miesiąc lipiec):

screenshot-20210709071611.png

Tym samym lipiec mam 3 razy + jakieś zera. Wydaje mi się, że coś jest nie tak z Case'ami i gdzieś chyba powinienem jeszcze wcisnąć uwzględnienie per klient:

over (partition by klient)

Poza tym sumowanie też działa niepoprawnie, gdy robię to ręcznie w Excelu w celu sprawdzenia.
Generalnie idea jest taka, aby mając bazę operacji finansowych klientów, wybrać do raportu tylko sumy dodatnich sald per klient. Jeśli suma kwot faktur firmy A jest większa od zero, ma ona zostać uwzględniony w sumie całkowitej. Jeśli jest mniejsza, firma ma być pominięta. Dodatkowo sumy powinny zostać zagregowane do miesięcy.
Będę wdzięczny za pomoc. Z góry dziękuję.

2
select s.*, s.akt+s.nieakt total from
(select to_char(date_trunc('month', data_salda),'YYYY-MM'),
       greatest(sum(case when t.status = 'Aktywny' then t.kwota else 0 end),0) akt,
       greatest(sum(case when t.status = 'Nieaktywny' then t.kwota else 0 end),0) nieakt
  from db.klienci_rozliczenia_historia  t
 group by 1) s
0

Dziękuję za poświęcony czas, jednak nie działa to tak, jak powinno. Nie wskazałem wcześniej, że kolumna "przeterminowane" jest typu money, więc musiałem dodać t.przeterminowane::numeric, aby nie wyrzucało błędów typu: CASE/WHEN nie może przekształcić typu money do integer Stan SQL: 42846. Być może źle wyjaśniłem, o co mi chodzi. W wyniku zapytania powinienem widzieć sumę kwot faktur tylko tych klientów, których saldo jest dodatnie (suma per klient >0). Nie bardzo rozumiem w jaki sposób Case w kodzie: greatest(sum(case when t.status = 'Aktywny' then t.kwota else 0 end),0) akt agreguje sumy per klient. Wg mnie działa to tylko tak, jakby 'greatest' sprawdzało, czy suma wszystkich faktur z danym statusem (ale bez odniesienia do danego klienta) jest większa od zero i zwracała tę kwotę. Gdzieś brakuje jeszcze tego odniesienia do sumy częściowej kwot per klient. To zapytanie uwzględnia niestety również klientów, których suma faktur (w odniesieniu do klienta) jest <0 bo któryś ma jakąś operację finansową "na plusie".
Wracając do mojego przykładu, na którym próbowałem objaśnić, o co chodzi - jeśli weźmiemy szczegółowe rozliczenie dla daty: 10.06.2021, widać, że suma kwot faktur klienta A wynosi plus (+) 190 000 zł, więc wszystkie 3 faktury powinny być uwzględnione w zapytaniu, bo klient jest dłużnikiem. Z drugiej jednak strony suma kwot faktur klienta B wynosi minus (-)266 000 zł, więc nie jest on dłużnikiem i niezależnie od tego, czy ma cokolwiek na plusie, suma wszystkich jego faktur jest <=0, więc wszystkie te faktury powinny zostać pominięte. Jeśli wcześniej nieprecyzyjnie określiłem problem to przepraszam i proszę ponownie o pomoc. Z góry dziękuję.

1

Jeśli potrzebujesz kwot dodatnich to możesz w case when dodac taki warunek
SQL Sum(case when t.status='aktywny' and t.kwota>0 then t.kwota else =0 end)

0

@kate87: Już sobie poradziłem. Moje zapytanie teraz wygląda mniej więcej tak:

SELECT m,
       sum(aktywni) AS "suma(aktywni)",
       sum(nieaktywni) AS "suma(nieaktywni)",
       sum(aktywni) + suma(nieaktywni) AS "suma(razem)"
FROM (SELECT to_char(date_trunc('month', data_salda),'YYYY-MM') AS m,
             greatest(sum(t.kwota) FILTER (WHERE t.status = 'Aktywny'), 0) AS aktywni,
             greatest(sum(t.kwota) FILTER (WHERE t.status = 'Nieaktywny'), 0) AS nieaktywni
      FROM db.klienci_rozliczenia_historia AS t
      GROUP BY m, klient) AS subq
GROUP BY m;

Działa jak należy. Dzięki mimo wszystko za pomoc!

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