Sumowanie narastające wg DATY - SQL

Sumowanie narastające wg DATY - SQL
Kazimierz Olejczyk
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:7
0

Witam,
mam w mej ocenie nie mały orzech do zgryzienia i już nie pierwszy dzień z tym walczę, stąd proszę o pomoc.

Mam przygotowane zapytanie z bazy, gdzie potrzebuję umieścić kolumnę, która będzie sumować:

  • pod warunkiem tego samego indeksu,
  • daty mniejszej, bądź równej tej z danego wiersza;
  • lokalizacji w magazynie (1,2,3,4)
    Zmiany na danym indeksie mogą być na plus (dostawa), bądź na minus (rozchód), stąd w danym wierszu potrzebuję sumę uwzględniającą zmianę przed (daty wcześniejsze), jak i uwzględniającą zmianę w danym wierszu. Odrębnie potrzebuję takie dane dla każdego z magazynów.

najlepiej obrazuje to przykładowa tabela poniżej:
screenshot-20190912115744.png

Bardzo liczę na pomoc, z góry dziękuję za zainteresowanie i chęć podzielenia się wiedzą i umiejętnościami.

PA
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 9 godzin
  • Postów:3876
0

Jaka baza?

Kazimierz Olejczyk
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:7
0

Witam,
zapewne ma wypowiedź zabrzmi mało profesjonalnie, aczkolwiek za profesjonalistę się nie uważam :)
Baza jest na środowisku Microsoft SQL Server, korzystam z oprogramowanie "Microsoft SQL Server Management Studio" do tworzenia niezbędnych widoków, czy przygotowywania raportowania przez inne aplikacje ciągnące dane z tej bazy.

Jeśli mało dokładnie to opisałem to nieświadomie, mam nadzieję, że informacja wystarczająca.

PA
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 9 godzin
  • Postów:3876
0

wersja?

Kazimierz Olejczyk
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:7
0

Windows Server 2008 R2 Standard

PA
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 9 godzin
  • Postów:3876
1

No to zostają joiny:

Kopiuj
select
    tb.indeks
    ,tb.magazyn
    ,tb.data
    ,max(tb.zmiana) zmiana
    ,sum(rs.zmiana) as suma
from
   tb
   left join tb rs on rs.indeks=tb.indeks
                      and rs.magazyn=tb.magazyn
                      and tb.data >= rs.data
 group by
     tb.indeks
    ,tb.magazyn
    ,tb.data
 order by
     3,1,2

http://sqlfiddle.com/#!18/5ceea/4

edytowany 1x, ostatnio: Panczo
Kazimierz Olejczyk
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:7
0

Dziękuję za szybką odpowiedź, już próbuję to rozwiązanie zaimplementować w mym zapytaniu, dla potrzeb raportu musiałem 17 tabel połączyć, już je identyfikuję i podejmuję próby...

Neutral
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 3 lata
  • Lokalizacja:Polanów
  • Postów:151
1
Kopiuj
select * from magazine;
Kopiuj
+--------+-----------+------------+---------+------+
| index1 | magazine1 | date1      | changed | sum1 |
+--------+-----------+------------+---------+------+
|    101 |         1 | 2019-09-12 |      20 |   20 |
|    102 |         1 | 2019-09-13 |      50 |   50 |
|    102 |         2 | 2019-09-14 |     -20 |  -20 |
|    101 |         2 | 2019-09-15 |      -5 |   -5 |
|    102 |         2 | 2019-09-16 |      -5 |  -25 |
|    101 |         1 | 2019-09-17 |      30 |   50 |
|    102 |         1 | 2019-09-18 |     -10 |   40 |
|    101 |         1 | 2019-09-19 |     100 |  150 |
+--------+-----------+------------+---------+------+
Kopiuj
select *, sum(changed) over (partition by index1, magazine1 order by date1) as sum2 from magazine order by date1;
Kopiuj
+--------+-----------+------------+---------+------+------+
| index1 | magazine1 | date1      | changed | sum1 | sum2 |
+--------+-----------+------------+---------+------+------+
|    101 |         1 | 2019-09-12 |      20 |   20 |   20 |
|    102 |         1 | 2019-09-13 |      50 |   50 |   50 |
|    102 |         2 | 2019-09-14 |     -20 |  -20 |  -20 |
|    101 |         2 | 2019-09-15 |      -5 |   -5 |   -5 |
|    102 |         2 | 2019-09-16 |      -5 |  -25 |  -25 |
|    101 |         1 | 2019-09-17 |      30 |   50 |   50 |
|    102 |         1 | 2019-09-18 |     -10 |   40 |   40 |
|    101 |         1 | 2019-09-19 |     100 |  150 |  150 |
+--------+-----------+------------+---------+------+------+

tutorial

edytowany 3x, ostatnio: Neutral
PA
Tylko na 2008 nie zadziała...
BlackBad
Tylko po prawdzie OP ostatecznie nie napisał jakiej wersji SQL Servera używa tylko na jakim Windowsie to stoi. Także to dalej jest zagadka.
RA
  • Rejestracja:prawie 7 lat
  • Ostatnio:8 dni
  • Postów:360
1

Będąc zalogowanym do bazy wersje można sprawdzić tak:

Kopiuj
Select @@version
Kazimierz Olejczyk
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:7
0

Nadal nie daje mi to spokoju, ciągle próbuję na szereg sposobów i nadal nie udaje mi się.
By cokolwiek podziałać muszę wpiąć się poprzez VPN-a, który jest na tyle niecodzienny., że internet na ten czas odcina :(

Sprawdziłem wersję SQL-a korzystając z podpowiedzi jak to zrobić i jest to "2012 SP1".

druga sugestia dla początkującego wydawała mi się prostsza i oto mam jej wynik, gdzie już nie wiele brakuje:

screenshot-20190912152648.png

czy to oznacza, że wystarczy, że dodam do "order by" jakiś index, który być może znajdę w tabeli rozróżniający poza datą?

Przyznam się szczerze, że nie spodziewałem się tak szybkiej pomocy, jestem pod mega wrażeniem.

_13th_Dragon
  • Rejestracja:prawie 20 lat
  • Ostatnio:8 dni
0

Zadziała dla MySQL:

Kopiuj
select
   m.*, 
   (select sum(s.changed) from magazine s where s.index1=m.index1 and s.magazine1=m.magazine1 and s.date1<=m.date1) as sum 
from
   magazine m 
order by
   m.date1;

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
PA
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 9 godzin
  • Postów:3876
1

Bez zapytania trudno poradzić, bo nie bardzo wiem gdzie jest kolumna suma z przykładu posta...
Podejrzewam, że chodzi o query - neutral i to, że jest to powielone w ramach jednej daty.
Jeżeli tak to albo faktycznie dodasz do order by indeks który będzie miał kolejność, albo sobie go "stworzysz":

Kopiuj
select
    lp
    ,indeks
    ,magazyn
    ,datac
    ,zmiana
    ,sum(zmiana) over (partition by indeks,magazyn order by lp) as suma
from (select
          row_number() over (partition by indeks,magazyn order by data) lp
          ,*
      from
          tb) as t
 order by
     2,3,4

http://sqlfiddle.com/#!18/5b073e/5

P.S. Co do VPN odchacz opcję "użyj domyślnej bramy w sieci zdalnej" to nie powinienes "gubic" netu

Kazimierz Olejczyk
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:7
0

Bardzo podobało mi się rozwiązanie 'PANCZO' i sporo energii włożyłem w jego implementację, aczkolwiek popłynąłem przy rozbudowie "FROM", gdzie potrzebowałem 3 tabele tam umiejscowić, dodatkowo tabelę z magazynami upraszczam poprzez "CASE" do 4 i niestety poległem, nie znaczy że przestaję szukać rozwiązania, być może na nowo zacznę, bo modyfikacja powstałej hybrydy jest ciekawa.

Teraz sobie myślę. że jak samo zapytanie działa to utworzę tabelę tymczasową i korzystając z tego zapytania wyrzucę całość plus pożądaną kolumnę, hmm..

PA
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 9 godzin
  • Postów:3876
1

To wykorzystaj cte, będzie łatwiej w zapisie:

Kopiuj
with tb as (
--miejsce na twoje zapytanie
)

--miejsce na moje zapytanie
select * from tb
edytowany 1x, ostatnio: Panczo
Kazimierz Olejczyk
zrobiłem dokładnie tak, sprawdzam rezultat, wygląda obiecująco...
Kazimierz Olejczyk
wszystko śmiga, serdeczne dzięki!!!
Kazimierz Olejczyk
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:7
0

Dziękuje wszystkim za chęć pomocy!!!
Nadal jestem w szoku, nie jedną zagwozdkę z SQL-em miałem, ale zawsze jakoś sam, sam i sam, co się kończyło nieprzespanymi nocami, bądź brakiem satysfakcji dnia następnego.

Dzięki podpowiedzią użytkownika Panczo i jego płynnemu dostosowaniu rozwiązania do mych postępów przy rozwikłaniu zagwozdki, co sprawia w moc metody GTD, że mam satysfakcję z dopracowania zapytania.

Naturalnie nie jestem na tyle mocny by jeszcze rad udzielać, ale stronę tą już dodałem do ulubionej, kto wie może za rok-dwa :)

Jeszcze raz DZIĘKI!!!

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.