ukulele
Datenbank-Guru
- Beiträge
- 5.306
So jetzt mal meine Lösung. Ich habe deine Testdaten vom Anfang des Threads genommen, da die aber so dicht bei einander lagen habe ich die in andere Monate geschoben. Später ging es ja nicht mehr um Tagessaldo sondern Wochensaldo zu Sonntag. Wichtig: Alle Umsätze aller Konten sind jetzt in einer Ausgangstabelle, wie sich das gehört. EB-Werte müssten da jetzt auch drin sein oder noch dazu geholt werden.
Bei mir am Server ist Montag der erste Tag der Wochem @@datefirst = 1 . Darüber kann man das noch dynamisch machen, den Schmerzen sind hier kaum Grenzen gesetzt
Ich generiere also alle Sonntage (letzter Tag der Woche) zu allen Jahren aus den Buchungen. Dazu noch jeweils den Jahresletzten Tag falls das kein Sonntag ist. Sonst fehlt ja irgendwie was... Dann eine Summe über alle Buchungen, darüber eine laufende Summe, zum Schluss noch ein Pivot um das Schema im ersten Thread abzubilden. Das Pivot ist nicht dynamisch, die Konten müssen fest eingetragen werden oder es muss noch ein dynamisches SQL draus werden.
Bei mir am Server ist Montag der erste Tag der Wochem @@datefirst = 1 . Darüber kann man das noch dynamisch machen, den Schmerzen sind hier kaum Grenzen gesetzt
Ich generiere also alle Sonntage (letzter Tag der Woche) zu allen Jahren aus den Buchungen. Dazu noch jeweils den Jahresletzten Tag falls das kein Sonntag ist. Sonst fehlt ja irgendwie was... Dann eine Summe über alle Buchungen, darüber eine laufende Summe, zum Schluss noch ein Pivot um das Schema im ersten Thread abzubilden. Das Pivot ist nicht dynamisch, die Konten müssen fest eingetragen werden oder es muss noch ein dynamisches SQL draus werden.
Code:
WITH buchungen(konto,wert,datum) AS (
SELECT 1,5,cast('2023-01-31' AS DATE) UNION ALL
SELECT 1,10,'2023-02-01' UNION ALL
SELECT 1,2,'2023-03-02' UNION ALL
SELECT 1,1,'2023-04-04' UNION ALL
SELECT 2,7,'2023-01-31' UNION ALL
SELECT 2,-5,'2023-02-01' UNION ALL
SELECT 2,3,'2023-03-03' UNION ALL
SELECT 3,3,'2023-01-01' UNION ALL
SELECT 3,4,'2023-02-03' UNION ALL
SELECT 3,5,'2023-03-04'
), basis(datum) AS (
--erster Tag eines jeden Jahres
SELECT DISTINCT dateadd(year,datepart(year,datum)-1900,0)
FROM buchungen
--Hier kann noch Logik erfolgen in der per @@datefirst erkannt wird welches der erste Tag der Woche für die DB ist.
WHERE @@datefirst = 1
), zeitreihe(datum) AS (
--letzter Tag eines jeden Jahres sofern kein Sonntag
SELECT dateadd(day,-1,dateadd(year,1,datum))
FROM basis
WHERE datepart(weekday,datum) != 7
UNION ALL
--erster Sonntag eines jeden Jahres
SELECT dateadd(day,7 - datepart(weekday,datum),datum)
FROM basis
UNION ALL
--alle weiteren Sonntage eines jeden Jahres
SELECT dateadd(day,7,datum)
FROM zeitreihe
WHERE datepart(year,datum) = datepart(year,dateadd(day,7,datum))
), wochensaldo(datum,konto,wert) AS (
SELECT z.datum,
k.konto,
--laufende Summe über die Summe zum Stichtag
sum(sum(b.wert)) OVER (PARTITION BY k.konto ORDER BY z.datum)
--alle Stichtage
FROM zeitreihe z
--alle Konten
CROSS JOIN ( SELECT DISTINCT konto FROM buchungen ) k
--alle Einzelbuchungen
LEFT JOIN buchungen b
ON k.konto = b.konto
--alle Buchungen der Woche
AND b.datum BETWEEN dateadd(day,-6,z.datum) AND z.datum
--nur der Anteil im laufenden Jahr (da letzter des Jahres eine eigene Position hat)
AND datepart(year,b.datum) = datepart(year,z.datum)
GROUP BY z.datum,k.konto
)
--Pivot der Konten
SELECT datum,
[1],[2],[3]
FROM wochensaldo
PIVOT ( sum(wert)
FOR konto
IN ([1],[2],[3]) ) AS p