Cross Join oder Right Join nur wie?

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.
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
 
Werbung:
Zurück
Oben