solardub
Goto Top

MSSQL: tägliche Berechnung rückwirkend für das Vormonat

Hallo Leute!

Ich habe derzeit eine Berechnung von Daten des Vortages.
Nun muss ich aber Rückwirkend das Vormonat jeden Tag einzeln berechnen.
Könnt Ihr mir vielleicht weiterhelfen wie ich das am besten hinbekommen kann?

Ich dachte mir, ich lese die Tage des Vormonates aus:

declare @d datetime
declare @tag as varchar(2)

set @d = dateadd(month, -1, CONVERT (date, GETDATE()))
select 32-day(@d-day(@d)+32)

Set @tag = 1

Und mache eine Loop
While @tag = @d
Begin
(Berechnung von Daten wo Monat-1 und Tag=@Tag)
Set @tag = @tag +1;
END;

Was haltet ihr davon?
Oder gibt's eine bessere Lösung?

Lg, Solardub

Content-Key: 400468

Url: https://administrator.de/contentid/400468

Printed on: April 19, 2024 at 01:04 o'clock

Member: it-frosch
it-frosch Feb 05, 2019 updated at 13:23:40 (UTC)
Goto Top
Hallo Solardub,

das kommt drauf an wie deine Daten vorliegen.
Mach doch deine Berechnung mit:

sum (x+y) where datediff(day,@d,current_timestamp)=30
sum(x+y) where datediff(month,@d,current_timestamp)=1
Es wäre auch hilfreich, wenn du das "Nun muss ich aber Rückwirkend das Vormonat jeden Tag einzeln berechnen." mal in verständliches Deutsch überträgt. face-wink
Dann versteht man besser, was du willst.

grüsse vom it-frosch
Member: Solardub
Solardub Feb 05, 2019 at 14:18:24 (UTC)
Goto Top
Ich möchte vom Vormonat jeden einzelnen Tag automatisch berechnen.

zb: SUM(CASE WHEN kz = 'A' THEN menge ELSE 0 END) - SUM(case WHEN kz = 'Z' THEN menge ELSE 0 END) AS Menge
von Monatsersten bis Monatsletzten

verständlicher?
Member: ukulele-7
ukulele-7 Feb 05, 2019 at 14:46:04 (UTC)
Goto Top
Kannst du mal einen Beispiel geben in welcher Form die aktuellen Datensätze und die des Vormonats vorliegen. Grundsätzlich kannst du die Daten zusammen joinen oder aggregieren, je nachdem wie die Daten aufgebaut sind.

Loop ist so ziemlich das letzte was man in SQL machen sollte, es gibt eigentlich nichts was langsammer und anfälliger arbeitet.
Member: Solardub
Solardub Feb 05, 2019 updated at 15:12:06 (UTC)
Goto Top
Also meine Abfrage sieht nun so aus:
DECLARE @tag as INT
DECLARE @monat as varchar(2)
DECLARE @year as varchar(4)

SET @monat = month(dateadd(month, -1, CONVERT (date, GETDATE())))
SET @year = year(dateadd(month, -1, CONVERT (date, GETDATE())))

SET @tag = 01

TRUNCATE TABLE [dev_LMTag]

WHILE @tag < 32
BEGIN
INSERT INTO [dev_LMTag]
Select
lag_AnlieferungsDatum
, lag_Artikel_Nr
, SUM(CASE WHEN lag_kz_zu_abgang = 'A' THEN lag_menge ELSE 0 END) - SUM(case WHEN lag_kz_zu_abgang = 'Z' THEN lag_menge ELSE 0 END) AS Menge
, lag_KostenStelle
from dbo.Lager
where ((lag_Artikel_Nr between 1000 and 4499) OR (lag_Artikel_Nr BETWEEN 8100 AND 8500))
and ((lag_KostenStelle between 1 AND 299) OR (lag_KostenStelle between 320 AND 349))
and year(lag_AnlieferungsDatum)=@Year
and MONTH(lag_AnlieferungsDatum)=@Monat
and DAY(lag_AnlieferungsDatum)=@Tag

group by lag_AnlieferungsDatum, lag_Artikel_Nr, lag_KostenStelle

Set @tag = @tag +1
print @tag
END;
Member: Solardub
Solardub Feb 05, 2019 at 15:36:31 (UTC)
Goto Top
Also es funktioniert und geht auch relativ schnell (6sec. bei ca. 20.000 Datensätze).
Oder kann man es schöner & effektiver lösen?
THX!!
Member: Solardub
Solardub Feb 05, 2019 at 15:37:56 (UTC)
Goto Top
ach ja, dbo.Lager ist ein View auf mehrere Datenbanken
Member: ukulele-7
Solution ukulele-7 Feb 05, 2019 at 15:38:08 (UTC)
Goto Top
Das sind ja keine Datensätze sondern eine Abfrage bzw. eigentlich keine Abfrage sondern eine Schleife mit ~31 Abfragen, Gruppierungen und Inserts also maximal unperformant.

Das kannst du schon ganz einfach kürzen und alle Datensätze die so entstehen mit
INSERT INTO [dev_LMTag]
Select
lag_AnlieferungsDatum
, lag_Artikel_Nr
, SUM(CASE WHEN lag_kz_zu_abgang = 'A' THEN lag_menge ELSE 0 END) - SUM(case WHEN lag_kz_zu_abgang = 'Z' THEN lag_menge ELSE 0 END) AS Menge  
, lag_KostenStelle
from dbo.Lager
where ((lag_Artikel_Nr between 1000 and 4499) OR (lag_Artikel_Nr BETWEEN 8100 AND 8500))
and ((lag_KostenStelle between 1 AND 299) OR (lag_KostenStelle between 320 AND 349))
AND		lag_AnlieferungsDatum BETWEEN dateadd(month,-1,getdate()) AND getdate()

group by lag_AnlieferungsDatum, lag_Artikel_Nr, lag_KostenStelle
einfügen. Dann bleiben aber Fragen wie z.B. wiso fügst du das in die Tabelle ein? Wiso nicht nur ein Select oder eine View.
Member: Solardub
Solardub Feb 06, 2019 at 10:54:41 (UTC)
Goto Top
Danke!
Ich brauche die täglich entstehenden Minuswerte die in einem Pool kommen und in die Berechnung des darauf folgenden Tages miteinbezogen werden, darum die Schleife.
Member: ukulele-7
ukulele-7 Feb 06, 2019 at 12:37:18 (UTC)
Goto Top
Wenn ich mich nicht täusche macht mein Code das selbe wie deiner nur ohne Schleife in einem Insert.
Member: Solardub
Solardub Feb 08, 2019 at 09:05:20 (UTC)
Goto Top
joop, macht er.
Hatte da wohl einen Denkfehler wegen der Minusmengen.